我正在创建一个可重复使用的 MetaControl
,它由一些子控件组成(参见图片)。它继承自 UIControl
,包含 2 个简单的 UIButtons
和一个我创建的自定义 slider 。 CustomSlider
也继承自 UIControl
。
在 MetaControl
的初始化程序中,我添加了一些目标操作,这些操作从子控件接收事件以通知 MetaControl
更改。
class MetaControl: UIControl {
public override init(frame: CGRect) {
self.slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
self.slider.addTarget(self, action: #selector(sliderTouched), for: .touchDown)
self.button1.addTarget(self, action: #selector(button1Pressed), for: .touchDown)
self.button2.addTarget(self, action: #selector(button2Pressed), for: .touchDown)
}
}
然后我放了选择器:
@objc private func sliderTouched() {
print("The slider was touched")
}
我遇到的问题是 sliderTouched()
事件。每当我触摸 slider 时,此事件都会触发两次。
- 第一次似乎是从
MetaControl
本身发送的。 - 第二次是从
CustomSlider
本身传递的正确事件。
我的问题是,如何防止 MetaControl
本身响应事件,同时仍然允许我的 CustomSlider
发送其操作?
我用了两种方法来确认是 MetaControl
本身触发了额外的事件:
注释掉
CustomSlider
中的 Action 发送代码。即使没有这行代码,sliderTouched()
仍然会被调用:class CustomSlider: UIControl { var isTouched = false { didSet { //sendActions(for: .touchDown) } } }
将
.touchDown
操作替换为.applicationReserved
。因为我不再使用.touchDown
,所以永远不会调用MetaControl
的.touchDown
事件。class CustomSlider: UIControl { var isTouched = false { didSet { sendActions(for: .applicationReserved) } } }
有趣的是,UIButtons
不会导致同样的问题。按下 UIButton
不会触发两个事件。我怎样才能实现同样的目标?
附言我导致事件从 CustomSlider
发送的方式是通过嵌入到 CustomSlider
自己的初始化程序中的自定义 UIPanGestureRecognizer
。
我以此为指导:https://www.raywenderlich.com/82058/custom-control-tutorial-ios-swift-reusable-knob
P.P.S 我希望我不会以错误的方式处理这个问题——将所有这些子控件嵌入到 MetaControl
中,然后它本身继承自 UIControl
。 MetaControl
本身从不响应触摸事件——只有子控件。我主要将 MetaControl
用作管理共享状态、为布局提供结构并使控件可重用的容器。最终,我需要很多。
最佳答案
答案是确保同时覆盖 slider 中的 touchesBegan
。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
关于ios - 阻止父 UIControl 响应 touchDown 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42589724/