如何将闭包作为动作来点击添加到UIView的手势?

时间:2019-01-14 15:28:48

标签: ios swift closures uitapgesturerecognizer

我想要一个UIView上的单击功能,但是我不知道如何在函数的第一张图片中传递该闭包:

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:2)

首先:我强烈建议您在问题中添加代码段而不是屏幕截图。

您需要在Selector中为操作参数传递UITapGestureRecognizer而不是() -> ()闭包:

extension UIView {
    func onClick(target: Any, _ selector: Selector) {
        isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: target, action: selector)
        addGestureRecognizer(tap)
    }
}

此外,请记住,此时您必须为target实例设置适当的tap,这意味着它在 not self中不是UIView扩展名(在您的代码中实现);相反,您必须将其作为参数传递给onClick方法。

用法:

在您的ViewController中:

likesImg.onClick(target: self, #selector(likesImgClicked))

@objc private func likesImgClicked() {
    print(#function)
}

likesImg.onClick(target: self时:self在这里是指ViewController本身,而不是UIView扩展名,这是正确的目标,因为likesImgClicked是在ViewController中实现的,而不是在{ {1}}扩展名。


更新:

如果您坚持采用关闭方法,则可以采用以下解决方案:

将您的UIView扩展实现为:

UIView

用法:

在您的ViewController中:

extension UIView {
    private struct OnClickHolder {
        static var _closure:()->() = {}
    }

    private var onClickClosure: () -> () {
        get { return OnClickHolder._closure }
        set { OnClickHolder._closure = newValue }
    }


    func onClick(target: Any, _ selector: Selector) {
        isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: selector)
        addGestureRecognizer(tap)
    }

    func onClick(closure: @escaping ()->()) {
        self.onClickClosure = closure

        isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(onClickAction))
        addGestureRecognizer(tap)
    }

    @objc private func onClickAction() {
        onClickClosure()
    }
}

重要提示:

感谢@Josh Caswell的以下注意事项:

  

请注意,私有结构为您提供了一个存储位置   整个程序。如果您尝试在多个视图上设置处理程序,   第二个将覆盖第一个。

答案 1 :(得分:2)

基于一些答案,我刚刚重塑了快速点击侦听器android样式。使用非常简单:

yourView.setClickListener {
    // do some actions here!
}

将此添加到扩展文件中:

final class ClickListener: UITapGestureRecognizer {
    private var action: () -> Void

    init(_ action: @escaping () -> Void) {
        self.action = action
        super.init(target: nil, action: nil)
        self.addTarget(self, action: #selector(execute))
    }

    @objc private func execute() {
        action()
    }
}

extension UIView {
    func setClickListener(_ action: @escaping () -> Void) {
        self.isUserInteractionEnabled = true
        let click = ClickListener(action)
        self.addGestureRecognizer(click)
    }
}

答案 2 :(得分:0)

我正在使用Xcode 11.7和Swift 5.2

我创建了一个普通的Button动作。请参考下面的代码

    import UIKit


    func customBarButton(_ target: Any, selector: Selector, controlEvent: UIControl.Event, buttonImage: String) -> UIBarButtonItem{
        let customButton = UIButton(type: .custom)
        customButton.setImage(UIImage(named: buttonImage), for: .normal)
        customButton.frame = CGRect(x: 0, y: 0, width: 24, height: 24)
        customButton.addTarget(target, action: selector, for: controlEvent)
        let filterItem = UIBarButtonItem(customView: customButton)

        return filterItem
    }

我已经在Viewcontroller文件中使用了上面的代码。

在viewdidload中初始化。

    let searchItem = customBarButton(self, selector: #selector(didTapSearchButton(_:)), controlEvent: .touchUpInside, buttonImage: "search")
    
    navigationItem.rightBarButtonItems = [searchItem]

触摸按钮时调用的功能:

@objc func didTapSearchButton(_ sender: Any){
 //enter code here
}