这是一个controller ,废话不多说直接上代码
import UIKit
import SnapKit
protocol ViewChainable {
}
class TestPushVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.red
self.navigationItem.title = "标题"
_ = UILabel()
.adhere(toSuperView: view)
.layout { (make) in
make.top.equalToSuperview().offset(80)
make.centerX.equalToSuperview()
}
.config { (label) in
标记A: label.backgroundColor = UIColor.clear
label.font = UIFont.systemFont(ofSize: 20)
label.textColor = UIColor.darkGray
label.text = "你好"
}
}
}
extension ViewChainable where Self:UIView {
@discardableResult // 消除警告
//“如果一个闭包表达式作为函数调用的最后一个实参,尾随闭包”
func config(_ config1: (Self) ->Void) -> Self {
标记B: config1(self)
return self
}
}
extension UIView:ViewChainable {
func adhere(toSuperView: UIView) -> Self {
toSuperView.addSubview(self)
return self
}
@discardableResult
func layout(snapKItMaker: (ConstraintMaker) ->Void) -> Self {
self.snp.makeConstraints { (make) in
snapKItMaker(make)
}
return self
}
}
这是大神们解说的其中一段话:
config 函数的实现,可以看到这里定义了一个名为 ViewChainable 的协议,然后对这个协议做了一个扩展,并让 UIView 实现了这个协议。这么做的原因在于,为了让 config 函数的闭包参数在实际使用中,闭包的第一个参数类型可以具体到 UIView 的不同子类上。拿上面的例子来说,UILabel 的实例在调用 config 函数时,所需的闭包参数类型就是 (UILabel) -> Void 而不是 (UIView) -> Void。
链式表面上看就是点语法的实现,要想自己实现点语法,要用extension 扩展。
从 标记B 到 标记A 是顺序实现: 先调用函数config 接着内部 调用闭包 ->调用自己代码逻辑