当前位置: 首页>编程语言>正文

Swift SnpKit 流程总结

首先UIView.snp是UIView扩展的计算属性,类型为ConstraintViewDSL(结构体).代码如下

public var snp: ConstraintViewDSL {

        return ConstraintViewDSL(view: self)

    }

常用的添加约束入口:

public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
        ConstraintMaker.makeConstraints(item: self.view, closure: closure)
    }

传入闭包closure, 用于收集各种约束, 具体由参数make: ConstraintMaker参与收集工作.

最终的收集处理工作由以下方法完成:

internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
        let maker = ConstraintMaker(item: item)
        closure(maker)
        var constraints: [Constraint] = []
        for description in maker.descriptions {
            guard let constraint = description.constraint else {
                continue
            }
            constraints.append(constraint)
        }
        return constraints
    }

其中closure(maker), 就是调用我们我们从外界添加的各约束, 具体: maker.descriptions就是所有的约束描述(每一项属于类——ConstraintDescription),其中的每一项就是类似make.left.right.equalToSuperview()一行代码的约束。另一个关键的代码:description.constraint,这是一个计算属性,会构造类Constraint,而这个类又会在它的构造方法里生成最终系统能识别的约束类型——LayoutConstraint继承NSLayoutConstraint。

下面说说make.left.right.equalToSuperview()怎么收集单行的所有约束描述:

make属于ConstraintMaker,首先make会调用

public var left: ConstraintMakerExtendable {

        return self.makeExtendableWithAttributes(.left)

    }

internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable {

        let description = ConstraintDescription(item: self.item, attributes: attributes)

        self.descriptions.append(description)

        return ConstraintMakerExtendable(description)

    }

left.right调用的是:

public var right: ConstraintMakerExtendable {

        self.description.attributes += .right

        return self

    }

之后会返回类型ConstraintMakerExtendable,而我们看到约束描述是存储于ConstraintMaker.descriptions : [ConstraintDescription], 这时我们会有一个疑问: ConstraintMakerExtendable执行下一次(如.right)约束时怎么把约束保存到ConstraintMaker.descriptions, 其实很简单, 首先ConstraintMakerExtendable持有ConstraintDescription , ConstraintDescription是一个类, 所有约束都会保存到ConstraintDescription的实例对象, 而具体每一项存入ConstraintDescription.attributes. 对于每一行约束只会执行一次make.descriptions.append(description), 多行时make.descriptions才有多个值, 对于一行的其他约束执行ConstraintMakerExtendable.description.attributes += .right, ConstraintMakerExtendable.description.attributes 属于 结构体ConstraintAttributes, 这个结构体遵守OptionSet协议, 即是一个集合枚举类型能存储top bottom left right 等。

原文地址:https://www.jianshu.com/p/bb38ced9dc1d

https://www.xamrdz.com/lan/54n2016065.html

相关文章: