有什么办法可以使以下在Swift 3中正常工作?
let button = UIButton().apply { $0.setImage(UIImage(named: "UserLocation"), for: .normal) $0.addTarget(self, action: #selector(focusUserLocation), for: .touchUpInside) $0.translatesAutoresizingMaskIntoConstraints = false $0.backgroundColor = UIColor.black.withAlphaComponent(0.5) $0.layer.cornerRadius = 5 }
该apply<T>功能应该采取型的封闭(T)->Void,运行它传递self到它,然后简单地返回self。
apply<T>
(T)->Void
self
另一个选择是为此使用运算符,例如“ =>”(从Kotlin和Xtend语言中借用了这个想法)。
=>
试图做这样的扩展NSObject:
NSObject
extension NSObject { func apply<T>(_ block: (T)->Void) -> T { block(self as! T) return self as! T } }
但是它需要在闭包中显式声明参数类型:
let button = UIButton().apply { (it: UIButton) in it.setImage(UIImage(named: "UserLocation"), for: .normal) it.addTarget(self, action: #selector(focusUserLocation), for: .touchUpInside) ...
这不方便,并且使整个想法不值得付出努力。类型已经在对象创建时指定,并且应该有可能不明确地重复它。
谢谢!
首先让我们定义HasApply协议
HasApply
protocol HasApply { }
和相关扩展
extension HasApply { func apply(closure:(Self) -> ()) -> Self { closure(self) return self } }
接下来让make NSObject符合HasApply。
extension NSObject: HasApply { }
让我们测试一下
let button = UIButton().apply { $0.titleLabel?.text = "Tap me" } print(button.titleLabel?.text) // Optional("Tap me")
我不会使用NSObject(这是Objective-C处事方式的一部分,我认为将来会在某些时候删除它)。我更喜欢类似的东西UIView。
UIView
extension UIView: HasApply { }