我只是想知道是否可以将函数传递给按钮操作(通常是选择器)。
例如,通常我会说:
UIBarButtonItem(title: "Press", style: .Done, target: self, action: "functionToCall")
func functionToCall() {
// Do something
}
但我想知道是否可以做类似的事情:
UIBarButtonItem(title: "Press", style: .Done, target: self, action: {
// Do Something
})
我想这样做的原因是因为我的功能非常简单,看起来它更整洁,更像Swift,因为它们强调它们在封闭上的重点。
答案 0 :(得分: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?()
}
}
它依赖于Objective-C运行时中的关联对象来添加闭包/块属性。
设置后,它会将目标更改为自身,并将选择器指向一个新函数,如果它存在,则调用该闭包。
有了这个,你可以随时设置任何actionClosure
的{{1}}并期望一切正常,这是一个例子:
UIBarButtonItem
答案 1 :(得分:1)
Reddit上的帖子使用自定义组件https://www.reddit.com/r/swift/comments/3fjzap/creating_button_action_programatically_using
解释了此解决方案要使用它,虽然我必须以编程方式而不是通过故事板添加Button。我是这样做的。
{
"title": "dfhhtryres",
"owner": "admin",
"code": "hfdsadfghdfh",
"linenos": false,
"language": "python",
"style": "friendly"
}
答案 2 :(得分:0)
不幸的是,Apple提供的初始化程序是不可能的。它在后台运行的方式是使用反射,并且提供闭包是完全不同的,目前不支持。
您可能可以通过一些黑客攻击来创建自定义解决方案,或者Apple可能会在将来引入该解决方案。
答案 3 :(得分:0)
typealias
,以清理语法。UIBarButtonItem
传递到操作处理程序中。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)
}
}