my navigation bar is not visible in my app - swift

I am trying to set up the a navigation bar and a WKWebview in my app, the webview is present but i am not able to see the navigation bar is not visible. What am i doing wrong?
I edited my code now it functions well this is the problem remaining.
This is my code
class MyController:UIViewController, WKNavigationDelegate{
var webView: WKWebView!
#IBOutlet weak var barView: UIView!
required init(coder aDecoder: NSCoder) {
self.webView = WKWebView(frame: CGRect.zero)
super.init(coder: aDecoder)!
self.webView.navigationDelegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
barView.frame = CGRect(x:0, y: 0, width: view.frame.width, height: 40)
view.insertSubview(webView, belowSubview: barView)
webView.translatesAutoresizingMaskIntoConstraints = false
let height = NSLayoutConstraint(item: webView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0)
let width = NSLayoutConstraint(item: webView, attribute: .width, relatedBy: .equal, toItem: view, attribute: .width, multiplier: 1, constant: 0)
view.addConstraints([height, width])
if((UserDefaults.standard.object(forKey:"language")as? String ?? "") == "en"){
let url = URL(string: "myurl")!
webView.load(URLRequest(url: url))
}
else{
let url = URL(string: "https://myurl")!
webView.load(URLRequest(url: url))
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
barView.frame = CGRect(x:0, y: 0, width: size.width, height: 40)
}
override func viewWillAppear(_ animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnSideMenuActn(_ sender: UIButton) {
self.pushViewControl(ViewControl:"SideMenuController")
}
}

Related

My subview can't be added to a UIView that is a subView of a UIView.xib file, it returns nil

I have two Swift files, one is called FileView.swift and the other is a FileViewController.swift. Using MVC Architecture, I am trying to add a subview from FileViewController.swift to FileView.swift's webViewContainer: UIView! which is an IBOutlet from a XIB File.
However, I am getting a nil result when it is called from FileViewController.swift.
class FileView: UIView {
#IBOutlet weak var webViewContainerHeight: NSLayoutConstraint!
#IBOutlet weak var webViewContainerWidth: NSLayoutConstraint!
#IBOutlet weak var closeBttnWidth: NSLayoutConstraint!
#IBOutlet weak var closeBttnHeight: NSLayoutConstraint!
#IBOutlet weak var webViewContainer: UIView!
#IBOutlet weak var closeButton: UIButton!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupNIB()
}
private func setup() {
webViewContainer = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 350))
}
class FileViewController: UIViewController, WKNavigationDelegate {
var webView = WKWebView()
var campaignUrl = ""
var finalCampaignUrl = ""
lazy var customView: FileView = {
let customView = FileView()
return customView
}()
override func loadView() {
self.view = self.customView
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
webViewModal()
}
func webViewModal () {
if UIDevice.current.userInterfaceIdiom == .pad {
let deviceWidth = UIScreen.main.bounds.width/3
let deviceHeight = UIScreen.main.bounds.height/3
customView.webViewContainerWidth.constant = 290 + deviceWidth
customView.webViewContainerHeight.constant = 475 + deviceHeight
customView.closeBttnWidth.constant = 55
customView.closeBttnHeight.constant = 55
customView.closeButton.layoutIfNeeded()
customView.webViewContainer.layoutIfNeeded()
}
webView = Global.setWKWebViewInitWithConfig(frame: .zero)
customView.webViewContainer.addSubview(webView)
customView.webViewContainer.showSpinner(CGSize(width: 30 , height: 30), tintColor: UIColor.lightGray)
webView.translatesAutoresizingMaskIntoConstraints = false
let webViewHeightConstraint = NSLayoutConstraint(
item: webView,
attribute: .height,
relatedBy: .equal,
toItem: customView.webViewContainer,
attribute: .height,
multiplier: 1,
constant: 0
)
let webViewWidthConstraint = NSLayoutConstraint(
item: webView,
attribute: .width,
relatedBy: .equal,
toItem: customView.webViewContainer,
attribute: .width,
multiplier: 1,
constant: 0
)
let webViewLeftMarginConstraint = NSLayoutConstraint(
item: webView,
attribute: .leftMargin,
relatedBy: .equal,
toItem: customView.webViewContainer,
attribute: .leftMargin,
multiplier: 1,
constant: 0
)
let webViewRightMarginConstraint = NSLayoutConstraint(
item: webView,
attribute: .rightMargin,
relatedBy: .equal,
toItem: customView.webViewContainer,
attribute: .rightMargin,
multiplier: 1,
constant: 0
)
let webViewBottomMarginContraint = NSLayoutConstraint(
item: webView,
attribute: .bottomMargin,
relatedBy: .equal,
toItem: customView.webViewContainer,
attribute: .bottomMargin,
multiplier: 1,
constant: 0
)
NSLayoutConstraint.activate([webViewHeightConstraint, webViewWidthConstraint, webViewLeftMarginConstraint, webViewRightMarginConstraint, webViewBottomMarginContraint])
webView.navigationDelegate = self
Global.initialLoadWithParam(ofWebView: webView, withURL: NSURL(string: campaignUrl)!)
customView.closeButton.layer.cornerRadius = 0.9 * customView.closeButton.bounds.size.width
customView.closeButton.backgroundColor = #colorLiteral(red: 0.003921568627, green: 0.1647058824, blue: 0.2666666667, alpha: 1)
customView.closeButton.tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
customView.webViewContainer.layer.cornerRadius = 15
customView.webViewContainer.layer.masksToBounds = true
}
I expected that this should add
webView = Global.setWKWebViewInitWithConfig(frame: .zero)
to
customView.webViewContainer.addSubview(webView)
but it returns nil instead on customView.webViewContainer's line:
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Should'nt webViewContainer already be instantiated when customView was loaded on override func loadView()?
The problem is that your webViewContainer is a weak reference:
class FileView: UIView {
// ...
#IBOutlet weak var webViewContainer: UIView!
// ...
}
This works fine if
you are using XIB files
someone (e.g.the view controller) keeps a strong reference to the top view
The outlets are part of the view hierarchy.
But in your case, in setup you create an instance of the view, store it in the weak reference, and then ARC (the reference counting mechanism) will find out that there are no strong references any more to the UIView and therfore clears the memory, resulting in a nil reference.
So you need to somehow keep a strong reference; in the simplest case, just skip the weak reference specifier in the outlet.
But keep in mind that you might have to do additional stuff to prevent strong reference cycles. In your case, if you do not work with xib files, you could just remove all the #IBOutlet stuff and make the NSCoder initializer just call fatalError, to prevent any creation from a xib file.

Text Cursor out of view when typing

I have multiple PDFKit annotations added into my PDF Document. When the user selects the text annotations to add text, the keyboard appears and the document scrolls upward and the cursor is no long on the screen. I have tried treating the PDF Document as a textfield but that does not work. How can I keep the cursor on screen or centered above the keyboard when the user adds text on the PDF Annotation?
Here is my code:
import UIKit
import PDFKit
class PDFfun: UIViewController {
var pdfView = PDFView()
var textFieldMultiline3 = PDFAnnotation()
let document = PDFDocument(url: Bundle.main.url(forResource: "DOCUMENT", withExtension: "pdf")!)
override func viewDidLoad() {
super.viewDidLoad()
pdfView = PDFView(frame: self.view.frame)
pdfView.document = document
pdfView.autoScales = true
pdfView.backgroundColor = UIColor.lightGray
self.insertMultilineTextBoxIntoOneOneNine(document!.page(at: 119)!)
pdfView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pdfView)
view.addConstraints([
NSLayoutConstraint(item: pdfView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0),
NSLayoutConstraint(item: pdfView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0),
NSLayoutConstraint(item: pdfView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: pdfView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
])
}
func insertMultilineTextBoxIntoOneOneNine(_ page: PDFPage) {
_ = page.bounds(for: .cropBox)
let textFieldMultilineBounds3 = CGRect(x: 27, y: 50, width: 339, height: 510)
textFieldMultiline3 = PDFAnnotation(bounds: textFieldMultilineBounds3, forType: PDFAnnotationSubtype(rawValue: PDFAnnotationSubtype.widget.rawValue), withProperties: nil)
textFieldMultiline3.widgetFieldType = PDFAnnotationWidgetSubtype(rawValue: PDFAnnotationWidgetSubtype.text.rawValue)
textFieldMultiline3.backgroundColor = UIColor.white.withAlphaComponent(1)
textFieldMultiline3.font = UIFont(name: "Arial", size: 15)
textFieldMultiline3.isMultiline = true
page.addAnnotation(textFieldMultiline3)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("landscape")
pdfView = PDFView(frame: view.frame)
pdfView.autoScales = true
} else {
print("portait")
pdfView = PDFView(frame: view.frame)
pdfView.autoScales = true
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
pdfView.frame = view.frame
}
override var prefersStatusBarHidden: Bool {
return false
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}

AdMob implement (only code, no main storyboard)

I want put Ad banner in my app.
I don't have the storyboard, I 've 4 ViewCOntroller, in the main I've this, can someone help me please?
In AppDelegate: GADMobileAds.configure(withApplicationID: "...")
import UIKit
import Firebase
import GoogleMobileAds
class ViewController: UIViewController {
var window: UIWindow?
override func viewDidLoad(){
super.viewDidLoad()
self.title="Andrea Damante Quiz"
self.view.backgroundColor=UIColor(patternImage: UIImage(named: "andrea15.jpeg")!)
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = UIImage(named: "andrea15.jpeg")
backgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(backgroundImage, at: 0)
setupViews()
}
#objc func btnGetStartedAction() {
let v=QuizVC()
self.navigationController?.pushViewController(v, animated: true)
}
func setupViews() {
self.view.addSubview(lblTitle)
lblTitle.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 150).isActive=true
lblTitle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive=true
lblTitle.widthAnchor.constraint(equalToConstant: 250).isActive=true
lblTitle.heightAnchor.constraint(equalToConstant: 80).isActive=true
self.view.addSubview(btnGetStarted)
btnGetStarted.heightAnchor.constraint(equalToConstant: 50).isActive=true
btnGetStarted.widthAnchor.constraint(equalToConstant: 150).isActive=true
btnGetStarted.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive=true
btnGetStarted.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive=true
}
let lblTitle: UILabel = {
let lbl=UILabel()
lbl.text="Quiz"
lbl.textColor=UIColor.darkGray
lbl.textAlignment = .center
lbl.font = UIFont.systemFont(ofSize: 46)
lbl.numberOfLines=2
lbl.translatesAutoresizingMaskIntoConstraints=false
return lbl
}()
let btnGetStarted: UIButton = {
let btn=UIButton()
btn.setTitle("Via!", for: .normal)
btn.setTitleColor(UIColor.white, for: .normal)
btn.backgroundColor=UIColor.orange
btn.layer.cornerRadius=5
btn.layer.masksToBounds=true
btn.translatesAutoresizingMaskIntoConstraints=false
btn.addTarget(self, action: #selector(btnGetStartedAction), for: .touchUpInside)
return btn
}()
}
You need to declare and set up a GADBannerView and add it to your view controller. You won't need a UIWindow. Use this code:
import GoogleMobileAds
import UIKit
class ViewController: UIViewController {
var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
// In this case, we instantiate the banner with desired ad size.
bannerView = GADBannerView(adSize: kGADAdSizeBanner)
addBannerViewToView(bannerView)
}
func addBannerViewToView(_ bannerView: GADBannerView) {
bannerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(bannerView)
view.addConstraints(
[NSLayoutConstraint(item: bannerView,
attribute: .bottom,
relatedBy: .equal,
toItem: bottomLayoutGuide,
attribute: .top,
multiplier: 1,
constant: 0),
NSLayoutConstraint(item: bannerView,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1,
constant: 0)
])
}
}
which was taken from here: https://developers.google.com/admob/ios/banner.
Also make sure to set the ad unit ID and the delegate:
override func viewDidLoad() {
super.viewDidLoad()
...
bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
bannerView.rootViewController = self
bannerView.load(GADRequest())
}
But again, you'll everything you need in the official guide.

How do I send subviews to front programmatically? (have tried bringSubview to front)

In my UICollectionViewCell I have an image and a label. The picture takes up the whole cell (which I want) - however, the label is placed behind the image, so it's not visible. I have tried bringSubview(toFront: titleLabel), but nothing happens... I got no clue what to do really, have done a lot of searching.
This is the code for the cell, I don't use Storyboard as you can see (sorry for messy constraints, was testing different solutions to find out if this was the problem)
import UIKit
class BaseCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupBasket()
}
func setupViews() {
}
func setupBasket(){
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class VideoCell: BaseCell {
var selectedItemID : String!
static let sharedInstance = VideoCell()
var video: Video? {
didSet {
titleLabel.text = video?.title
setupThumbnailImage()
}
}
func setupThumbnailImage() {
if let thumbnailImageUrl = video?.thumbnail_image_name {
thumbnailImageView.loadImageUsingUrlString(thumbnailImageUrl)
}
}
let thumbnailImageView: CustomImageView = {
let imageView = CustomImageView()
imageView.image = UIImage(named: "taylor_swift_blank_space")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
let titleLabel: UILabel = {
let textView = UILabel()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.text = "Clothes"
textView.textColor = UIColor.lightGray
return textView
}()
let separatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 230/255, green: 230/255, blue: 230/255, alpha: 1)
return view
}()
var titleLabelHeightConstraint: NSLayoutConstraint?
let addtoBasket = UIButton(type: .contactAdd)
override func setupViews() {
addtoBasket.frame = CGRect(x: 50, y: 0, width: 20, height: 60)
addSubview(addtoBasket)
addSubview(titleLabel)
addSubview(thumbnailImageView)
addSubview(separatorView)
addSubview(addtoBasket)
titleLabel.superview!.bringSubview(toFront: titleLabel)
//horizontal constraints
addConstraintsWithFormat("H:|-0-[v0]-0-|", views: thumbnailImageView)
//vertical constraints
addConstraintsWithFormat("V:|-1-[v0]-1-|", views: thumbnailImageView)
addConstraintsWithFormat("H:|-0-[v0]-1-|", views: separatorView)
addtoBasket.translatesAutoresizingMaskIntoConstraints = false
addtoBasket.heightAnchor.constraint(equalToConstant: 20).isActive = true
addtoBasket.widthAnchor.constraint(equalToConstant: 20).isActive = true
addtoBasket.centerXAnchor.constraint(equalTo: addtoBasket.superview!.centerXAnchor, constant: 90).isActive = true
addtoBasket.centerYAnchor.constraint(equalTo: addtoBasket.superview!.centerYAnchor, constant: -50).isActive = true
//top constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .top, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 8))
//right constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0))
//right constraint
addConstraint(NSLayoutConstraint(item: titleLabel, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 20))
//height constraint
titleLabelHeightConstraint = NSLayoutConstraint(item: titleLabel, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1, constant: -10)
addConstraint(titleLabelHeightConstraint!)
}
}
Try accessing the labels layer and set its zPosition.
Try titleLabel.layer.zPosition = 1
There was clearly something wrong with the constraints, now working! Thanks

How to implement multiple PanGestures (Draggable views)?

I want to have several objects that I can drag and drop.
Here's my code for moving one object (with lot of help from #vacawama):
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var panView: UIView!
#IBOutlet weak var panViewCenterX: NSLayoutConstraint!
#IBOutlet weak var panViewCenterY: NSLayoutConstraint!
let panRec = UIPanGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
panRec.addTarget(self, action: "draggedView:")
panView.addGestureRecognizer(panRec)
// Do any additional setup after loading the view, typically from a nib.
}
func draggedView(sender:UIPanGestureRecognizer){
self.view.bringSubviewToFront(sender.view!)
var translation = sender.translationInView(self.view)
panViewCenterY.constant += translation.y
panViewCenterX.constant += translation.x
sender.setTranslation(CGPointZero, inView: self.view)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I want to have more objects in my project:
#IBOutlet weak var panView2: UIView!
#IBOutlet weak var panView3: UIView!
#IBOutlet weak var panView4: UIView!
...
So, what is the easiest way to implement this in such way that I can have multiple panView which I can move independently around (one at the time)?
If you are using Auto Layout, you shouldn't just move a view by altering its center. Anything that causes Auto Layout to run will move your view back to its original position.
Here is an implementation of a new class called DraggableView that works with Auto Layout to provide views that can be dragged. It creates constraints in code for the width, height, X position, and Y position of the view. It uses its own UIPanGestureRecognizer to allow the view to be dragged.
DraggableView.swift can be dropped into any project that needs draggable views. Take a look at ViewController.swift below to see how easy it is to use.
DraggableView.swift
import UIKit
class DraggableView: UIView {
let superView: UIView!
let xPosConstraint: NSLayoutConstraint!
let yPosConstraint: NSLayoutConstraint!
var constraints: [NSLayoutConstraint] {
get {
return [xPosConstraint, yPosConstraint]
}
}
init(width: CGFloat, height: CGFloat, x: CGFloat, y: CGFloat, color: UIColor, superView: UIView) {
super.init()
self.superView = superView
self.backgroundColor = color
self.setTranslatesAutoresizingMaskIntoConstraints(false)
let panGestureRecognizer = UIPanGestureRecognizer()
panGestureRecognizer.addTarget(self, action: "draggedView:")
self.addGestureRecognizer(panGestureRecognizer)
let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: width)
self.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height)
self.addConstraint(heightConstraint)
xPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal,
toItem: superView, attribute: .Leading, multiplier: 1.0, constant: x)
yPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal,
toItem: superView, attribute: .Top, multiplier: 1.0, constant: y)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func moveByDeltaX(deltaX: CGFloat, deltaY: CGFloat) {
xPosConstraint.constant += deltaX
yPosConstraint.constant += deltaY
}
func draggedView(sender:UIPanGestureRecognizer){
if let dragView = sender.view as? DraggableView {
superView.bringSubviewToFront(dragView)
var translation = sender.translationInView(superView)
sender.setTranslation(CGPointZero, inView: superView)
dragView.moveByDeltaX(translation.x, deltaY: translation.y)
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let dragView1 = DraggableView(width: 75, height: 75, x: 50, y: 50,
color: UIColor.redColor(), superView: self.view)
self.view.addSubview(dragView1)
self.view.addConstraints(dragView1.constraints)
let dragView2 = DraggableView(width: 100, height: 100, x: 150, y: 50,
color: UIColor.blueColor(), superView: self.view)
self.view.addSubview(dragView2)
self.view.addConstraints(dragView2.constraints)
let dragView3 = DraggableView(width: 125, height: 125, x: 100, y: 175,
color: UIColor.greenColor(), superView: self.view)
self.view.addSubview(dragView3)
self.view.addConstraints(dragView3.constraints)
}
}
UPDATE:
Here is a version of DraggableView.swift that supports images as a subview.
import UIKit
class DraggableView: UIView {
let superView: UIView!
let xPosConstraint: NSLayoutConstraint!
let yPosConstraint: NSLayoutConstraint!
var constraints: [NSLayoutConstraint] {
get {
return [xPosConstraint, yPosConstraint]
}
}
init(width: CGFloat, height: CGFloat, x: CGFloat, y: CGFloat, color: UIColor, superView: UIView, imageToUse: String? = nil, contentMode: UIViewContentMode = .ScaleAspectFill) {
super.init()
self.superView = superView
self.backgroundColor = color
self.setTranslatesAutoresizingMaskIntoConstraints(false)
let panGestureRecognizer = UIPanGestureRecognizer()
panGestureRecognizer.addTarget(self, action: "draggedView:")
self.addGestureRecognizer(panGestureRecognizer)
let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: width)
self.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height)
self.addConstraint(heightConstraint)
xPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal,
toItem: superView, attribute: .Leading, multiplier: 1.0, constant: x)
yPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal,
toItem: superView, attribute: .Top, multiplier: 1.0, constant: y)
if imageToUse != nil {
if let image = UIImage(named: imageToUse!) {
let imageView = UIImageView(image: image)
imageView.contentMode = contentMode
imageView.clipsToBounds = true
imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.addSubview(imageView)
self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1.0, constant: 0))
self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: 0))
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func moveByDeltaX(deltaX: CGFloat, deltaY: CGFloat) {
xPosConstraint.constant += deltaX
yPosConstraint.constant += deltaY
}
func draggedView(sender:UIPanGestureRecognizer){
if let dragView = sender.view as? DraggableView {
superView.bringSubviewToFront(dragView)
var translation = sender.translationInView(superView)
sender.setTranslation(CGPointZero, inView: superView)
dragView.moveByDeltaX(translation.x, deltaY: translation.y)
}
}
}
The way a gesture recognizer works is that you attach it to a view. So if you have multiple views, and you want them to be draggable in the same way, attach a different pan gesture recognizer to each one.
Now let's say you want them all to have the same action handler. No problem. In the action handler, you receive the current gesture recognizer as a parameter. It has a view property; that's the view it is attached to! So now you know that that's the view you're moving.
Finally:
Found this example which explained it in a easy way:
http://www.raywenderlich.com/76020/using-uigesturerecognizer-with-swift-tutorial
So, now multiple Pan's are working..
Here's the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var boxToMove1: UIView!
#IBOutlet weak var boxToMove2: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func handlePan(objectToMove:UIPanGestureRecognizer) {
let translation = objectToMove.translationInView(self.view)
objectToMove.view!.center = CGPoint(x: objectToMove.view!.center.x + translation.x, y: objectToMove.view!.center.y + translation.y)
objectToMove.setTranslation(CGPointZero, inView: self.view)
println("\(objectToMove.view!.tag)") //Verify correct object received
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I linked up the "Pan Gesture Recognizer" from the "Object library" to each boxToMove. Then I linked the "Pan Gesture Recognizer" (both) to my #IBAction func handlePan...
This is now working!!!
Finally I understand the way this Gesture Recognizer is working!
What I'm still trying to figure out is how to do all this linking programmatically.. Any idea?