Such as title, I have a superView A and a childView B. The A has a panGestureRecognizer. When I swipe the B, it will trigger the panGestureRecognizer of A. So I return No in the shouldReceiveTouch of A, But the panGestureRecognizer still works whick makes me confused.
I used the following and it seems to work as expected:
class ViewController: UIViewController {
private lazy var topView: UIView = {
let view = UIView(frame: .init(x: 100.0, y: 200.0, width: 200.0, height: 200.0))
view.backgroundColor = UIColor.green
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
let bottomView = self.view
bottomView?.backgroundColor = UIColor.red
bottomView?.addSubview(topView)
bottomView?.addGestureRecognizer({
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(onPan))
panGesture.delegate = self
return panGesture
}())
}
private var stateString: String = "" {
didSet {
if stateString != oldValue {
print("State changed to \(stateString)")
}
}
}
@objc private func onPan(_ sender: UIGestureRecognizer) {
switch sender.state {
case .began: stateString = "begin"
case .changed: stateString = "changed"
case .ended: stateString = "ended"
case .cancelled: stateString = "canceled"
default: stateString = "some thing else"
}
}
}
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return topView.bounds.contains(touch.location(in: topView)) == false
}
}
A gesture only works when started out of the green view. Once a gesture has started then events will be triggered normally as they should, that includes within the green view.