ios - 阻止父 UIControl 响应 touchDown 事件

标签 ios swift uicontrol target-action

我正在创建一个可重复使用的 MetaControl,它由一些子控件组成(参见图片)。它继承自 UIControl,包含 2 个简单的 UIButtons 和一个我创建的自定义 slider 。 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() 事件。每当我触摸 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 中,然后它本身继承自 UIControlMetaControl 本身从不响应触摸事件——只有子控件。我主要将 MetaControl 用作管理共享状态、为布局提供结构并使控件可重用的容器。最终,我需要很多。

enter image description here

最佳答案

答案是确保同时覆盖 slider 中的 touchesBegan

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

关于ios - 阻止父 UIControl 响应 touchDown 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42589724/

相关文章:

iphone - 在屏幕上的随机位置显示 UIImageView

IOS - 在一处管理所有字体

ios - 更改 iOS 滑动操作的 bool 值

ios - 如何设置条形图缩放的特定限制

ios - Xcode 中分配检测模板中持久和 transient 列的真正含义

c++ - 未定义模板的隐式实例化 'std::basic_string<char, std::char_traits<char>, std::allocator<char>>'

swift - 使用 cocoa/osx/swift 更改图像的分辨率和大小(无移动应用程序)

ios - 使用自定义drawRect代码创建UIButton LIKE控件

objective-c - UIControl 子类 - 事件调用两次

ios - 如何以非侵入方式检测 UIControl 之外任何地方的交互?