阻止父UIControl响应touchDown事件

时间:2017-03-03 22:44:43

标签: ios swift uicontrol target-action

我正在创建一个可重用的MetaControl,它包含一些子控件(参见图片)。它继承自UIControl,包含2个简单的UIButtons和我创建的自定义滑块。 CustomSlider也继承自UIControl

enter image description here

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()事件。每当我触摸滑块时,此事件都会被触发两次。

  • 第一次似乎是从MetaControl本身发送的。
  • 第二次是从CustomSlider本身传递的正确事件。

我的问题是,如何阻止MetaControl本身对事件做出响应,同时仍允许CustomSlider发送其动作?

我使用了两种方法来确认是MetaControl本身触发了额外的事件:

  • CustomSlider中注明了发送代码的操作。即使没有这行代码,仍然会调用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不会导致触发两个事件。我怎样才能实现同样的目标呢?

P.S。我导致从CustomSlider发送事件的方式是通过自定义UIPanGestureRecognizer嵌入CustomSlider自己的初始化程序。

我将此用作指南:https://www.raywenderlich.com/82058/custom-control-tutorial-ios-swift-reusable-knob

P.P.S我希望我不会以错误的方式解决这个问题 - 将所有这些子控件嵌入到MetaControl中,然后本身继承自UIControlMetaControl本身从不响应触摸事件 - 只响应子控件。我主要使用MetaControl作为容器来管理共享状态,为布局提供结构,并使控件可重用。最终,我需要很多。

enter image description here

1 个答案:

答案 0 :(得分:1)

答案是确保在滑块中覆盖touchesBegan

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}