提问人:Yasic 提问时间:10/20/2023 更新时间:10/20/2023 访问量:36
手势识别器、UIControl 和 UIButton 的事件响应优先级
Event response priorities for gesture recognizers, UIControl, and UIButton
问:
我有一个添加了手势识别器的父视图。父视图包含一个 UIButton 和一个 UIControl,分别添加了相应的操作。
代码如下
class MyViewController: UIViewController {
private lazy var parentView = UIView()
private lazy var button = UIButton(frame: .zero)
private lazy var control = UIControl(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(parentView)
parentView.addSubview(button)
parentView.addSubview(control)
parentView.backgroundColor = .red
button.backgroundColor = .yellow
control.backgroundColor = .blue
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleParentViewTapped))
parentView.addGestureRecognizer(tapGesture)
button.addTarget(self, action: #selector(handleButtonClicked), for: .touchUpInside)
control.addTarget(self, action: #selector(handleControlClicked), for: .touchUpInside)
parentView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
button.snp.makeConstraints { make in
make.leading.top.equalToSuperview()
make.size.equalToSuperview().multipliedBy(0.5)
}
control.snp.makeConstraints { make in
make.trailing.bottom.equalToSuperview()
make.size.equalToSuperview().multipliedBy(0.5)
}
}
@objc func handleParentViewTapped() {
print("view tapped")
}
@objc func handleButtonClicked() {
print("button clicked")
}
@objc func handleControlClicked() {
print("UIControl clicked")
}
}
我依次点击了 UIButton 和 UIControl,控制台打印顺序如下
button clicked
view tapped
如您所见,单击 UIButton 可以触发 UIButton 对应的操作,但单击 UIControl 将触发手势识别器的回调。
接下来,我将父视图的手势识别器设置为 false。这一次,手势识别器、UIButton 和 UIControl 的回调都将被调用。cancelsTouchesInView
view tapped
button clicked
view tapped
UIControl clicked
我的问题是
- 既然 UIButton 也是从 UIControl 继承而来的,为什么 UIButton 的事件响应优先级高于父视图的手势识别器,而 UIControl 却低于父视图的手势识别器?
- 如果我有一个自定义的 UIControl,并且想要达到与 UIButton 相同的优先级效果,我应该如何实现?
- 我知道如果手势识别器的cancelsTouchesInView设置为false,则click事件将继续传递给UIControl,因此UIControl可以响应该事件。但是,为什么 UIButton 和手势识别器都可以在 cancelsTouchesInView 设置为 false 后响应事件?
答: 暂无答案
评论