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?
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.