Swift像闭包一样使用select器参数

我只是想知道是否有可能将一个函数传递给一个button操作(通常是一个select器)。

例如,通常我会说:

UIBarButtonItem(title: "Press", style: .Done, target: self, action: "functionToCall") func functionToCall() { // Do something } 

但我想知道是否有可能做到这样的事情:

 UIBarButtonItem(title: "Press", style: .Done, target: self, action: { // Do Something }) 

我想这样做的原因是因为我的function是非常简单的,看起来它会更整洁,更像Swift,就像他们将重点放在closures上一样。

这是Swift 3的一个更新的解决scheme。

 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?() } } 

这是一个没有子类别的替代解决scheme:

 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?() } } 

它依靠Objective-C运行时的关联对象来添加一个闭包/块属性。

设置时,它将目标更改为自身,并将select器指向一个调用闭包(如果存在)的新函数。

有了这个,在任何时候你可以设置任何UIBarButtonItem并期望一切工作,这里是一个例子:

 let button = UIBarButtonItem( barButtonSystemItem: .action, target: nil, action: nil ) button.actionClosure = { print("hello") } 

Reddit上的一篇文章解释了一个自定义组件的解决scheme – https://www.reddit.com/r/swift/comments/3fjzap/creating_button_action_programatically_using

要使用它,虽然我不得不通过编程添加button,而不是通过故事板。 这是我是如何做到的。

 let tempVariableIWantToReference = "Classy" navigationTitle.leftBarButtonItem = BlockBarButtonItem.init( title: "< Back", style: UIBarButtonItemStyle.Plain, actionHandler: { () -> Void in print("Hey I'm in a closure") print("I can even reference temporary variables. \(self.tempVariableIWantToReference)!!!") }) 

不幸的是,苹果公司提供的初始设备是不可能的。 在后台工作的方式是使用reflection,提供一个闭包是完全不同的东西,目前不支持。

您可能可以通过一些黑客手段创build自定义解决scheme,或者将来可能会引入Apple。