在没有IBOutlet的情况下使用带有UIButton的IBActions,可以通过以下方法实现:
在你的UIViewController中,你可以使用UIButton的addTarget方法来添加一个事件处理程序,如下所示:
let button = UIButton(type: .system)
button.setTitle("点击我", for: .normal)
button.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
self.view.addSubview(button)
然后,你需要在你的UIViewController中实现buttonClicked方法,如下所示:
@objc func buttonClicked(sender: UIButton) {
print("按钮被点击了")
}
你还可以使用闭包来实现UIButton的点击事件处理程序,如下所示:
let button = UIButton(type: .system)
button.setTitle("点击我", for: .normal)
button.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
self.view.addSubview(button)
button.handleControlEvent(.touchUpInside) { [weak self] sender in
guard let self = self else { return }
print("按钮被点击了")
}
在这个例子中,我们使用了一个名为handleControlEvent的方法,它接受一个UIControl.Event枚举值和一个闭包作为参数。这个方法的实现如下所示:
extension UIControl {
func handleControlEvent(_ event: UIControl.Event, closure: @escaping (UIControl) -> Void) {
let sleeve = ClosureSleeve(closure: closure)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: event)
objc_setAssociatedObject(self, String(ObjectIdentifier(self).hashValue) + String(event.rawValue), sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
private class ClosureSleeve {
let closure: (UIControl) -> Void
init(closure: @escaping (UIControl) -> Void) {
self.closure = closure
}
@objc func invoke(sender: UIControl) {
closure(sender)
}
}
}
这个方法使用了一个名为ClosureSleeve的私有类,它包含一个闭包,并且可以将闭包转换为一个Selector,这样就可以将闭包作为UIButton的事件处理程序。
通过以上两种方法,你可以在没有IBOutlet的情况下使用带有UIButton的IBActions。
领取专属 10元无门槛券
手把手带您无忧上云