【问题标题】:Selectors in Swift 4.0Swift 4.0 中的选择器
【发布时间】:2018-04-09 23:50:27
【问题描述】:

我想知道是否有更“swift 4”的方式来创建选择器和调用函数?我希望单击状态栏按钮以从函数中调用简单的打印命令,但这是否已过时或者是否有更有效的“快速”方式来执行此操作?

button.action = #selector(myFunction)

@objc func myFunction (sender: NSStatusBarButton) {
    print("Hi")
}

【问题讨论】:

  • 这是 Objective-C 目标/动作遗留 API 的价格。
  • 您所拥有的正是这样做的方法。 Cocoa Touch 应用仍然使用 Objective-C 运行时,这就是选择器的接口。

标签: ios swift selector swift4


【解决方案1】:

我不确定是否有什么好的方法可以避免使用幕后的目标/动作模式,但你绝对可以尝试隐藏它。

我个人对所有回调都使用 ReactiveSwift,所以我永远不必使用这种尴尬的 objc 语法。另一种方法是将其隐藏在扩展中。例如,您可以尝试以下操作:

extension UIButton {

    private struct AssociatedKeys {
        static var TouchUpClosure = "touchUpClosure"
    }

    internal var onTouchUpInside: ((UIButton) -> ())? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.TouchUpClosure) as? (UIButton) -> ()            
        }

        set {
            objc_setAssociatedObject(
                self,
                &AssociatedKeys.TouchUpClosure,
                newValue as? (UIButton) -> (), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
            )
            button.action = #selector(executeTouchUpInside:)
        }
    }

    @objc func executeTouchUpInside(sender: UIButton) {
        self.touchUpInside(sender)
    }
}

这允许您使用“更快速”的语法(没有 @objc#selector):

button.onTouchUpInside = { _ in print("Hi") }

免责声明 - 我没有检查这个确切的代码是否编译,这篇文章更多的是分享一个想法。

【讨论】:

  • 您还需要将按钮的目标设置为self,以便调用本地操作。
  • 还要避免混淆使用UIButton (UIControl) addTarget 与问题的NSStatusBarButton (NSControl) 分开的actiontarget 属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多