【发布时间】:2020-12-05 20:56:24
【问题描述】:
假设您有一个尺寸小于其子视图的父视图。您将超级视图的clipsToBound 属性设置为false。如果点击子视图超出父视图边界的突出区域,为什么命中测试返回nil?
我的理解是命中测试从子视图开始,一直到超级视图。那么为什么要晚于子视图进行测试的父视图的属性很重要呢?或者命中测试是从根目录开始到树视图,比如视图控制器->主视图->子视图?
我从here 找到了一个自定义命中测试,它确实允许您点击超视图边界之外的子视图区域,但我不确定为什么颠倒子视图的顺序会有所不同(它有效,我只是不确定为什么)。我的示例甚至只有一个子视图。
class ViewController: UIViewController {
let superview = CustomSuperview(frame: CGRect(origin: .zero, size: .init(width: 100, height: 100)))
let subview = UIView(frame: CGRect(origin: .zero, size: .init(width: 200, height: 200)))
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.superview)
self.superview.backgroundColor = .red
self.superview.clipsToBounds = false
self.superview.addSubview(self.subview)
self.subview.backgroundColor = .blue
let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
self.subview.addGestureRecognizer(tap)
}
@objc func tapped(_ sender: UIGestureRecognizer) {
print("tapped")
}
}
class CustomSuperview: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if clipsToBounds || isHidden || alpha == 0 {
return nil
}
for subview in subviews.reversed() {
let subPoint = subview.convert(point, from: self)
if let result = subview.hitTest(subPoint, with: event) {
return result
}
}
return nil
}
}
【问题讨论】:
标签: ios swift touch-event hittest