Search code examples
iosswiftuitapgesturerecognizer

Bar button item custom view not detecting UITapGesture


I am encountering some weird behavior, where a subview within a UIBarButtonItem.customView is not firing the tapGesture.

private var leftBarButtonItem: UIBarButtonItem = {
    let b = UIBarButtonItem()
    return b
}()

private lazy var imageView: UIImageView = {
    let iv = UIImageView()
    //... some adicional setup
    iv.isUserInteractionEnabled = true
    return iv
}()


func setupBBItem() {
    let holderView = UIView()
    holderView.isUserInteractionEnabled = true
    
    holderView.addSubview(imageView)
    imageView.frame = //... some frame
    //... more setups here
    
    holderView.isUserInteractionEnabled = true
    
    
    leftBarButtonItem.customView = holderView
    navigationItem.leftBarButtonItem = leftBarButtonItem
    
    let gesture = UITapGestureRecognizer(target: self, action: #selector(someFunction))
    imageView.addGestureRecognizer(gesture)
}

@objc private func someFunction() {
    print("tap gesture detected")
}

I have even tried to add the gesture to the holderView instead, but the result is the same, the function never fires.

Am I missing something here?


Solution

  • The problem is this line:

    let holderView = UIView()
    

    That is a zero size view. So its subview, the image view, can be seen but cannot be tapped, because any part of a view that is outside its superview is untouchable by the user. You need to give the holder view some size, making it at least as big as the image view. And in particular you must do this, both for the holder view and for the image view, using autolayout constraints internally. That is how a bar button item custom view gets its size.