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.

Code Block
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?

Accepted Reply

So, I have figured this out.

The problem was that I wasn't applying any constraints to the holderView, so even though the views were shown, the actual size was 0, because it was visible out of bounds.

Note that setting a CGRect size to the holderView didn't solve the issue. I really had to set its constraints to the superview - in this case the leftBarButtonItem.customView

Replies

You create imageView without giving any image. Hence it has zero size.

Could be that causes the problem.

Try to change init :
Code Block
let iv = UIImageView(image: someImage)

So, I have figured this out.

The problem was that I wasn't applying any constraints to the holderView, so even though the views were shown, the actual size was 0, because it was visible out of bounds.

Note that setting a CGRect size to the holderView didn't solve the issue. I really had to set its constraints to the superview - in this case the leftBarButtonItem.customView
In setupBBItem(), you create holderView with let holderView = UIView().
The no-argument initializer of UIView is not documented, but I guess it generates a UIView of size zero.

Try giving it some size.
Code Block
        let holderView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 44))



Seems you have found another solution.
But as far as I tried, constraints are not needed if initialized with frame.