1

我正在创建一个MetaControl由几个子控件组成的可重用(见图)。它继承自UIControl,并包含我创建的 2 个简单UIButtons的自定义滑块。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()事件。每当我触摸滑块时,此事件都会触发两次。

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

我的问题是,我怎样才能防止它MetaControl本身响应事件,同时仍然允许我CustomSlider发送它的动作?

我使用了 2 种方法来确认是它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

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

我以此为指导:https ://www.raywenderlich.com/82058/custom-control-tutorial-ios-swift-reusable-knob

PPS 我希望我不会走错路——将所有这些子控件嵌入到一个MetaControl它本身继承自UIControl. 它MetaControl本身从不响应触摸事件——只有子控件。我MetaControl主要使用容器来管理共享状态,为布局提供结构,并使控件可重用。最终,我需要他们中的许多人。

在此处输入图像描述

4

1 回答 1

1

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

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
于 2017-03-04T09:35:59.287 回答