【问题标题】: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。关于你的问题。它不能工作的原因有很多。从视图层次结构开始。也许按钮下放置了另一个视图。
  • 我也遇到了这种情况。也写在这里:stackoverflow.com/a/47999822/1265393

标签: ios swift


【解决方案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.,该操作被触发。这意味着它将找到视图控制器中实现的方法并执行它。
猜你喜欢
  • 2014-11-13
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多