1

So I'm up to the point that I'm creating UIViews programmatically based on the amount of an array which is returned from JSON. Everything seems to be going ok except for the loop which is supposed to add the tap to each of the views but it is only adding it to one view. Only prints on the last UIView.

func addsubviews(howmany: Int) -> Void{
    let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap"))

for x in 1...howmany{

    guard let v = UINib(nibName: "DealsView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as? UIView else { return }

    v.translatesAutoresizingMaskIntoConstraints = false
    guard let lbl = v.viewWithTag(99) as? UILabel else { return }
    lbl.text = "Here is a new Label for Loop: " + "\(x)"

    self.allContainer.addSubview(v)

    v.backgroundColor = UIColor.white

    var horizontalConstratint1 = NSLayoutConstraint()
    var horizontalConstratint2 = NSLayoutConstraint()
    var verticalConstraint1 = NSLayoutConstraint()

    heightConstraint = v.heightAnchor.constraint(equalToConstant: 100)
    horizontalConstratint1 = v.leadingAnchor.constraint(equalTo: (v.superview?.leadingAnchor)!, constant: 10)
    horizontalConstratint2 = v.trailingAnchor.constraint(equalTo: (v.superview?.trailingAnchor)!, constant: -10)

    if prevView == nil{
        verticalConstraint1 = v.topAnchor.constraint(equalTo: (v.superview?.topAnchor)!, constant: 20)
        }else
    {
        if let pv = prevView as? UIView {
           verticalConstraint1 = v.topAnchor.constraint(equalTo: (pv.bottomAnchor), constant: 20)
        }
    }
    NSLayoutConstraint.activate([horizontalConstratint1,horizontalConstratint2,verticalConstraint1])

    prevView = v
        }

    if let pv = prevView as? UIView {
        print("final constratint")
        NSLayoutConstraint.activate([
            self.allContainer.bottomAnchor.constraint(equalTo: pv.bottomAnchor, constant: 20)
            ])
    }

    for views in self.allContainer.subviews{
        print("adding views")
        views.addGestureRecognizer(tap)
    }

}

After some trial and error...

The tap recognizer added for each loop:

        let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(sender:)))

the action which will be where the action goes on the tap:

func handleTap(sender: UITapGestureRecognizer) {
    // You can get the view here by writing
    let myv = sender.view
    print(myv)
}
BostonMacOSX
  • 1,369
  • 2
  • 17
  • 38

1 Answers1

3

You have just a single UITapGestureRecognizer before your view loop starts. AFAIK, tap gesture recognizers can only be attached to one view at a time. Check out this question. To solve this, try writing this line:

let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap"))

inside your view loop.


To find out what view was tapped, make your selector handleTap take an argument like so:
Selector("handleTap:")

and the method itself like this:

func handleTap(sender: UITapGestureRecognizer? = nil) {
    // You can get the view here by writing
    let v = sender.view
}
Community
  • 1
  • 1
aksh1t
  • 5,410
  • 1
  • 37
  • 55
  • That is cool...worked...just wondering how I can identify what UIVIew is getting tapped....I want to have a modal window appear with and call data based on what UIVIEW got tapped – BostonMacOSX Oct 01 '16 at 17:34
  • akshit I'm getting : 2016-10-01 19:26:56.092 JSONTesting[15648:1330158] -[JSONTesting.DealsController handleTap:]: unrecognized selector sent to instance 0x7fccb0e0a9d0 updated code above..... – BostonMacOSX Oct 01 '16 at 23:28
  • If you are using swift 2.2, the selector syntax is like this: #selector(MyControllerName.handleTap(_:)), I think that's what causing this error. – aksh1t Oct 02 '16 at 00:33
  • Swift 3 see above...the end of the answer I worked it out...thanks for all your help – BostonMacOSX Oct 02 '16 at 01:30
  • No problem! Glad I could be of help :) – aksh1t Oct 02 '16 at 01:58