通过视图层次结构传播触摸事件(UIView中的UIButton)

时间:2019-03-07 19:59:52

标签: ios cocoa-touch uibutton uitapgesturerecognizer

可以肯定这是一件容易的事,但仍然无法在互联网上找到任何类似的东西–还有一个理由认为这不是问题。反正!

我如何put a UIButton inside a UIView并在视图中添加UITapGestureRecognizer并在同时执行按钮操作的同时在此视图中调用函数?

我所拥有的:

  • 在按钮内部点击只会执行按钮操作。
  • 在按钮外部点击仅执行视图功能。

我想要的:

  • 在按钮内部点击可以同时执行按钮操作和查看功能。
  • 在按钮外部点击仅执行视图功能。

更新(我使用的代码):

import UIKit
import AwesomeFramework

class View: UIView {

    let button = UIButton()
    let awesomeObject = AwesomeFramework.AwesomeObject()

    @objc func a(_ sender: Any) {
        // never gets called
        print("a")
    }

    init() {
        super.init(frame: .zero)

        button.translatesAutoresizingMaskIntoConstraints = false
        addSubview(button)
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: centerXAnchor),
            button.centerYAnchor.constraint(equalTo: centerYAnchor),
            button.widthAnchor.constraint(equalTo: widthAnchor),
            button.heightAnchor.constraint(equalTo: heightAnchor),
            ])

        button.addTarget(awesomeObject, action: #selector(awesomeAction), for: .touchUpInside) // awesomeAction prints "b"

        let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(a(_:)))
        addGestureRecognizer(gestureRecognizer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

点击我想要的按钮

b
a

a
b

我得到:

b

更新:对示例进行了一些限制,例如:

  • 该按钮触发了我无权访问的框架中的操作
  • 实际上有许多按钮和其他分接接收元件。我不想对所有人都使用a函数(同样,由于某些元素管理自己的识别器,我也不能这样做)

2 个答案:

答案 0 :(得分:0)

在UITapGestureRecognizer的选择器内,您可以检查触发手势的视图。并且由于您可以访问该视图,因此可以检查发送视图的标签并确定它是否由您的按钮触发了。

这是您的操作方式:

@objc func a(_ sender: Any) {
    if let gesture = sender as? UITapGestureRecognizer, let v = gesture.view, v.tag == self.button.tag {
        return //since it has the tag same as that you had set for button, return
    }
    // else do what you wanted to.
}

您可以将选择器链接为:

#selector(a(_:))

并定义为:

func a(_ sender: Any) { .....}

请务必通过以下操作为按钮添加标签:

self.button.tag = 9 //(or any number you prefer)

答案 1 :(得分:0)

一个按钮可以有多个目标。告诉按钮同时触发ab

button.addTarget(self, action: #selector(a), for: .touchUpInside)
button.addTarget(self, action: #selector(b), for: .touchUpInside)

如果用户将手指放在按钮上,然后在释放之前将其拖出按钮怎么办?如果您希望它也触发a操作,请执行以下操作:

button.addTarget(self, action: #selector(a), for: .touchUpOutside)