2017-03-03 73 views
0

我正在创建一个可重用MetaControl,它由几个子控件组成(请参阅图片)。它继承自UIControl,并包含2个简单的UIButtons和我创建的自定义滑块。 CustomSlider也从UIControl继承。防止父UIControl响应touchDown事件

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送自己的行动?

我用2种方法来确认它是MetaControl本身,这触发了额外的事件:

  • 注释掉行动在CustomSlider发送代码。即使没有这行代码,sliderTouched()仍称:

    class CustomSlider: UIControl { 
        var isTouched = false { 
         didSet { 
          //sendActions(for: .touchDown) 
         } 
        } 
    } 
    
  • .applicationReserved取代了.touchDown行动。由于我不再使用.touchDown,所以MetaControl.touchDown事件从不会被调用。

    class CustomSlider: UIControl { 
        var isTouched = false { 
         didSet { 
          sendActions(for: .applicationReserved) 
         } 
        } 
    } 
    

有趣的是,UIButtons导致同样的问题。按UIButton不会导致触发两个事件。我怎样才能做到这一点?

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

我用这个作为一个准则:https://www.raywenderlich.com/82058/custom-control-tutorial-ios-swift-reusable-knob

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

enter image description here

回答

0

答案是一定要在滑块还覆盖touchesBegan

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