1 用户点击屏幕后产生的一个触摸事件,经过一系列的传递过程后,会找到最合适的视图控件来处理这个事件
2 找到最合适的视图控件后,就会调用控件的touches方法来作具体的事件处理。touchesBegan…touchesMoved…touchedEnded…
3 这些touches方法的默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理
我们可以试验一下,一个简单的VC的View只有一个SubView的App,对touches的处理,
如果我们不写next?.touchesBegan(touches, with: event),那么点击SubView只有一个print,因为当前的响应者就是那个subview
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| extension UIApplication { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("UIApplication touchesBegan") next?.touchesBegan(touches, with: event) } }
extension UIViewController { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("UIViewController touchesBegan") next?.touchesBegan(touches, with: event) } }
extension UIView { open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("UIView touchesBegan") next?.touchesBegan(touches, with: event) } }
|
带上next?.touchesBegan(touches, with: event),可以看到输出如下
1 2 3 4 5 6
| UIView touchesBegan UIViewController touchesBegan UIView touchesBegan UIView touchesBegan UIView touchesBegan UIApplication touchesBegan
|
我们也可以按照系统的思路实现自己的hitTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class HitTestExampleView: UIView { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if !isUserInteractionEnabled || isHidden || alpha <= 0.01 { return nil } if self.point(inside: point, with: event) { for subview in subviews.reversed() { let convertedPoint = subview.convert(point, from: self) let resultView = subview.hitTest(convertedPoint, with: event) if resultView != nil { return resultView } } return self } return nil } }
|