sanch
sanch

Reputation: 716

Adding Tap Gesture to any view triggers nothing

I am dealing with the single most frustrating issue so far in my journey to iOS development. I originally was trying to add a gesture recognizer to my UIImage view but was not having any luck. I did some searching on stack and found that I hadn't set imageView.isUserInteractionEnabled = true which I figured would solve my problem but it didn't. So then I started adding gesture recognizers to everything including the parent view of imageView but still got nothing. I am sure that something I am doing/haven't done is so simple but I have just totally missed it. Please help.

ProfileViewController: UIViewController {

    // User's info container (Parent iof imageView)
let userInfoContainer: UIView = {
    let head = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    head.backgroundColor = UIColor.white
    head.translatesAutoresizingMaskIntoConstraints = false
    head.layer.borderWidth = 1
    print(head.isUserInteractionEnabled) // Returns true
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    head.addGestureRecognizer(tap)
    return head
}()
// Users name
let userName: UITextField = {
    let name = UITextField()
    name.text = "John Doe"
    name.translatesAutoresizingMaskIntoConstraints = false
    name.isUserInteractionEnabled  = true
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    name.addGestureRecognizer(tap)
    return name
}()

    // User's profile image
let profileImageView: UIImageView = {
    let imageView = UIImageView(image: #imageLiteral(resourceName: "avatar"))
    imageView.layer.cornerRadius = 50
    imageView.layer.masksToBounds = true
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.isUserInteractionEnabled = true
    imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapped)))
    return imageView
}()
//
//
// skipping other UI elements
//
//
override func viewDidLoad() {
    super.viewDidLoad()
    // Authentication bits

    self.title = "Profile View"
    self.view.backgroundColor = UIColor.white
    self.view.addSubview(userInfoContainer)
    self.view.addSubview(profileImageView)
    self.view.addSubview(userName)
    } // end viewDidLoad
func tapped() {
    print(123)
}

// setup constraints
func setupUserInfoContainer() {
    userInfoContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    userInfoContainer.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    userInfoContainer.heightAnchor.constraint(equalToConstant: 200).isActive = true
}
// profile image arrangement
func setupProfileImage() {
    profileImageView.leftAnchor.constraint(equalTo: userInfoContainer.leftAnchor, constant: 20).isActive = true
    profileImageView.centerYAnchor.constraint(equalTo: userInfoContainer.centerYAnchor).isActive = true
    profileImageView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: 100).isActive = true

}

func setupLabels() {
    userName.leftAnchor.constraint(equalTo: profileImageView.rightAnchor, constant: 20).isActive = true
    userName.centerYAnchor.constraint(equalTo: profileImageView.centerYAnchor).isActive = true
    userName.heightAnchor.constraint(equalToConstant: 20).isActive = true
    userName.isEnabled = false
}
} // end view controller

Rendered View: ProfileViewController View Hierarchy ViewHeiarchy Extra information that is likely not necessary: ProfileViewController is being handled by a UITabBarController but from what I have seen, that shouldn't make a difference.

Update From looking around it looks like the appropriate swift 3 syntax is let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:))) but I think having that line in the closure is what's causing this error to be thrown ../ProfileViewController.swift:37:74: Value of type '(NSObject) -> () -> ProfileViewController' has no member 'tapped'

If someone could explain how I can fix this that would be stellar.

Upvotes: 0

Views: 1022

Answers (3)

Kwaku Eshun
Kwaku Eshun

Reputation: 149

Why don't you just initiliaise your image view at the top of the class like

 let profileImageView = UIImageView()

and create a function to configure the imageview and add it as a subview such in view did load. That should work

func configureImageView() { 
    #add methods and customize image view
    #add image view to sub view 
} 

Upvotes: 0

DonMag
DonMag

Reputation: 77690

I don't believe you can assign a gesture recognizer in this manner...

1 let profileImageView: UIImageView = {
2     let imageView = UIImageView(image: #imageLiteral(resourceName: "avatar"))
3     imageView.layer.cornerRadius = 50
4     imageView.layer.masksToBounds = true
5     imageView.translatesAutoresizingMaskIntoConstraints = false
6     imageView.isUserInteractionEnabled = true
7     imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapped)))
8     return imageView
9 }()

On line 7, what is self? It is the function that is returning a UIImageView.

Your func tapped() is not part of that function... it belongs to ProfileViewController.

You might be able to find a way to change the target, but a couple minutes of trying different approaches has not yielded any luck for me.

I think you need to create and add the GestureRecognizer(s) inside ProfileViewController / viewDidLoad() (or elsewhere within that class).

Upvotes: 1

Ender
Ender

Reputation: 13

The problem is you didn't set delegate to the tap gesture. Check this

Hope this will work

Upvotes: 0

Related Questions