2017-03-03 107 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?) { 
}