?
如图上图所示,居于中心的是ConstraintDescription
,它用来生成Constraint
,最后再转换成系统的NSLayoutConstraint
。
ConstraintDescription
包含约束必备的所有因素
internal let item: LayoutConstraintItem internal var attributes: ConstraintAttributes internal var relation: ConstraintRelation? = nil // 记录产生约束的位置 internal var sourceLocation: (String, UInt)? = nil // 标签 internal var label: String? = nil internal var related: ConstraintItem? = nil internal var multiplier: ConstraintMultiplierTarget = 1.0 internal var constant: ConstraintConstantTarget = 0.0 internal var priority: ConstraintPriorityTarget = 1000.0
当前的item
(一般是UIView
) 的什么属性 attributes
要和哪个目标(related
)发生什么关系(relation
),优先级是什么(priority
),具体要怎么发生关系(multiplier
,constant
)
Constraint
SnapKit
的约束对象,用于生成NSLayoutConstraint
。
仅通过 ConstraintDescription
生成。
LayoutConstraintItem
即被约束的对象,在iOS
开发中,即为UIView
。
通过关联对象的方法,持有了很多Constraint
private var constraintsSet: NSMutableSet { let constraintsSet: NSMutableSet if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSMutableSet { constraintsSet = existing } else { constraintsSet = NSMutableSet() objc_setAssociatedObject(self, &constraintsKey, constraintsSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } return constraintsSet }
也有add(constraints)
、remove(constraints)
等方法,但是仅供框架内部调用。
ConstraintItem
被约束的对象+被约束的属性。
??,它有一个weak
属性,一般指向了UIView,避免了循环引用。
这个类,在创建约束时,被大量使用。
ConstraintMaker
它提供了静态方法来创建ConstraintDescription
,然后根据ConstraintDescription
来生成Constraint
。
ConstraintViewDSL
即我们调用的snp
。它并不是UIView
的存储属性,和函数调用更加接进。每一次调用snp
,都会生成一个ConstraintViewDSL
结构体。
public extension ConstraintView { ... public var snp: ConstraintViewDSL { return ConstraintViewDSL(view: self) } }
它提供了我们常用的方法,比如makeConstraints
、updateConstraints
、prepareConstraints
等。
这些方法,最终都调用了ConstraintMaker
的方法,来生成约束。
ConstraintDSL 协议
被ConstraintViewDSL
遵守,用来产生各种ConstraintItem
,从而生成约束。