将目标添加到闭包内的按钮不起作用

Posted

技术标签:

【中文标题】将目标添加到闭包内的按钮不起作用【英文标题】:Adding a target to button inside a closure doesn't work 【发布时间】:2018-06-27 11:12:34 【问题描述】:

以下代码位于 UIView 的子类中

我在闭包内设置了cancelButton

private var cancelButtonClosure: UIButton = 
    ...
    button.addTarget(self, action: #selector(cancel(_:)), for: .touchUpInside)
    ...
()

起初我在一个函数中实例化了按钮,如下所示:

func showConfirmationView(...) 
    ...
    let cancelButton = self.cancelButtonClosure
    ...
    addSubview(cancelButton)
    ...

然而,这导致取消函数根本没有被调用(即使布局正确并且按钮突出显示)

所以我做了这些改变:

cancelButtonClosure 中删除了addTarget 部分 在showConfirmationView 函数中添加了addTarget 部分

所以看起来是这样的:

func showConfirmationView(...) 
    ...
    let cancelButton = self.cancelButtonClosure
    cancelButton.addTarget(self, action: #selector(cancel(_:)), for: .touchUpInside)
    ...
    addSubview(cancelButton)
    ...

成功了:cancel 函数被调用;但我不知道为什么。我真的很想知道为什么我之前所做的没有奏效。感谢您的见解!

【问题讨论】:

您的cancelButtonClosure 并不是真正的闭包,而是它的结果(UIButton 的实例),因为您立即使用() 执行它。这也意味着您的行 let cancelButton = self.cancelButtonClosure 不会实例化按钮(因为它已经是),而是将其分配给 cancelButton 变量。 注意事项: 1. 不要将您的按钮命名为cancelButtonClosure。因为这是您在 中描述的关闭的结果。所以将其命名为cancelButton,它将是您已经初始化的按钮。 2.let cancelButton = self.cancelButtonClosure没有初始化按钮。在这种情况下,您将self.cancelButtonClosure 上的引用设置为cancelButton 变量,仅此而已。正如我之前写的那样,只使用self.cancelButtoncancelButton。关于你的问题。它不能工作的原因有很多。从视图层次结构开始。也许按钮下放置了另一个视图。 我也遇到了这种情况。也写在这里:***.com/a/47999822/1265393 【参考方案1】:

检查您的实施,因为这样的设置按预期工作:

private var cancelButton: UIButton = 
    let btn = UIButton(type: .system)
    btn.setTitle("Cancel", for: .normal)
    btn.addTarget(self, action: #selector(cancelSomething(_:)), for: .touchUpInside)
    return btn
()

@objc func cancelSomething(_ sender: UIButton) 
    print("Something has to be cancelled")


override func viewDidLoad() 
    super.viewDidLoad()
    showConfirmationView()


func showConfirmationView() 
    cancelButton.sizeToFit()
    cancelButton.center = view.center

    view.addSubview(cancelButton)

【讨论】:

我知道这段代码可以工作,但是如果你在取消块中打印 self ,它会打印(函数),为什么会这样?这是否意味着块中的 self 代表块本身?如果这是真的,那么我们如何将块本身作为目标参数中的参数? 是的。 self 正在引用闭包本身。实际上在这种情况下它没有任何意义(并且可以替换为nil),因为闭包在执行后将不再存在。所以target参数实际上是nil。然而,由于When the target object of a control is nil, UIKit starts from the target object and traverses the responder chain until it finds an object that implements the appropriate action method.,该操作被触发。这意味着它将找到视图控制器中实现的方法并执行它。

以上是关于将目标添加到闭包内的按钮不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何使按钮内的图标像按钮一样工作(指针事件:无;不起作用)

回调闭包函数在单元格中不起作用

NavigationLink 内的 tvOS 按钮不起作用

目标 C:如果将标签添加到单元格,则 UITable 方法“didSelectRowAtIndexPath”不起作用

UIButton 在子视图控制器中不起作用

Windows 8 应用程序将点击事件添加到超链接按钮不起作用