Chr*_*att 22 closures ios swift
我只是想知道是否可以将一个函数传递给一个按钮动作(通常是一个选择器).
例如,通常我会说:
UIBarButtonItem(title: "Press", style: .Done, target: self, action: "functionToCall")
func functionToCall() {
// Do something
}
Run Code Online (Sandbox Code Playgroud)
但我想知道是否可以做以下事情:
UIBarButtonItem(title: "Press", style: .Done, target: self, action: {
// Do Something
})
Run Code Online (Sandbox Code Playgroud)
我想要这样做的原因是因为我的功能非常简单,看起来它更整洁,更像Swift,因为它们强调它们放在封闭上.
Dav*_*vid 13
这是Swift 3的更新解决方案.
class BlockBarButtonItem: UIBarButtonItem {
private var actionHandler: ((Void) -> Void)?
convenience init(title: String?, style: UIBarButtonItemStyle, actionHandler: ((Void) -> Void)?) {
self.init(title: title, style: style, target: nil, action: #selector(barButtonItemPressed))
self.target = self
self.actionHandler = actionHandler
}
convenience init(image: UIImage?, style: UIBarButtonItemStyle, actionHandler: ((Void) -> Void)?) {
self.init(image: image, style: style, target: nil, action: #selector(barButtonItemPressed))
self.target = self
self.actionHandler = actionHandler
}
func barButtonItemPressed(sender: UIBarButtonItem) {
actionHandler?()
}
}
Run Code Online (Sandbox Code Playgroud)
Niñ*_*ipt 10
这是一个没有子类化的替代解决方案:
extension UIBarButtonItem {
private struct AssociatedObject {
static var key = "action_closure_key"
}
var actionClosure: (()->Void)? {
get {
return objc_getAssociatedObject(self, &AssociatedObject.key) as? ()->Void
}
set {
objc_setAssociatedObject(self, &AssociatedObject.key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
target = self
action = #selector(didTapButton(sender:))
}
}
@objc func didTapButton(sender: Any) {
actionClosure?()
}
}
Run Code Online (Sandbox Code Playgroud)
它依赖于Objective-C运行时的关联对象来添加闭包/块属性.
设置时,它将目标更改为自身,并将选择器指向一个新函数,如果存在,则调用该闭包.
有了这个,在任何时候你都可以设置actionClosure
任何一个UIBarButtonItem
并期望一切正常,这是一个例子:
let button = UIBarButtonItem(
barButtonSystemItem: .action,
target: nil, action: nil
)
button.actionClosure = {
print("hello")
}
Run Code Online (Sandbox Code Playgroud)
typealias
为函数签名添加 a以清理语法。UIBarButtonItem
到符合 Cocoa 约定的操作处理程序中。import UIKit
class SwiftBarButtonItem: UIBarButtonItem {
typealias ActionHandler = (UIBarButtonItem) -> Void
private var actionHandler: ActionHandler?
convenience init(image: UIImage?, style: UIBarButtonItem.Style, actionHandler: ActionHandler?) {
self.init(image: image, style: style, target: nil, action: #selector(barButtonItemPressed(sender:)))
target = self
self.actionHandler = actionHandler
}
convenience init(title: String?, style: UIBarButtonItem.Style, actionHandler: ActionHandler?) {
self.init(title: title, style: style, target: nil, action: #selector(barButtonItemPressed(sender:)))
target = self
self.actionHandler = actionHandler
}
convenience init(barButtonSystemItem systemItem: UIBarButtonItem.SystemItem, actionHandler: ActionHandler?) {
self.init(barButtonSystemItem: systemItem, target: nil, action: #selector(barButtonItemPressed(sender:)))
target = self
self.actionHandler = actionHandler
}
@objc func barButtonItemPressed(sender: UIBarButtonItem) {
actionHandler?(sender)
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,Apple 提供的初始化程序无法实现这一点。它在后台工作的方式是通过反射,而提供闭包是完全不同的,目前不支持。
您也许可以通过一些黑客技术创建自定义解决方案,或者 Apple 可能会在未来推出该解决方案。
归档时间: |
|
查看次数: |
5371 次 |
最近记录: |