I'm trying to detect when a user taps between items in a UIStackView. Subclassing UIStackView and overriding hitTest and pointInside doesn't work. Those only get called when I tap on an item.
Is there any way to achieve this?
Thanks!
You can add Transparent views instead of space between UIStackView.
Step 1:Add a view and make spacing in stack view zero
Step 2:Make the view color transparent
Step 3: Add Tap Gesture to this view
Step 4: Add action to the gesture and handle it accordingly
You can find a sample here
You need to add tap gesture recognizer to stack view.
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(stackViewTapped))
tapGesture.numberOfTapsRequired = 1
self.stackView.addGestureRecognizer(tapGesture)
@objc func stackViewTapped() {
print("Stack View tapped")
}
The issue is that somehow iOS doesn't track views that are transparent. So I ended up adding an almost transparent view, which restores tracking between items:
let invisibleTrackingView = InvisibleTrackingView(frame: mainStackView.frame)
invisibleTrackingView.backgroundColor = UIColor.clear.withAlphaComponent(0.001)
mainStackView.addSubview(invisibleTrackingView)
class InvisibleTrackingView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
return nil
}
}
The 0.001 value is the lowest that will work and is so low that the view is virtually transparent. Since the view returns false and nil, the OS goes down the view chain until one of them is a match.
I would suggest you to add a non text button to the UIStackView
and use it as the separator. Therefore you can add an IBAction
for the button.
You can reach the same if you add a UIView and then an UIGestureRecognizer
to the UIView
.
For how to add a UIGestureRecognizer
check this link