SnapKit源码解读

SnapKit源码解读

什么是Snapkit

        SnapKit是一个使用 Swift 编写而来的AutoLayout 框架,通过使用Snapkit,我们可以通过简短的代码完成布局,使用

view.snp.makeConstraints {
    (make) in
    make.center.equalToSuperview()
}

DSL(Domain specific Language)特定领域语言
        DSL是为了解决某些特定场景下的任务而专门设计的语言。如果能把一些设计师产出的长宽、色值、文字、居中、距上等设计元数据(设计的标注信息等),以一种约定的简洁的语言规则(即DSL)输入给程序代码,由程序和代码自动的分析和处理,从而生成真正的界面开发代码setFrame,setTitle,setColor,addSubview,这样就可以大幅度的减少代码量与工作量,程序员来写这种简洁的语法规则会更快更高效,甚至可以把这种简洁的语法规则教会设计师,让设计师有能力直接写出DSL,然后输入给底层程序,这样界面就自然完成。
分析源码
lable.snp通过给view加扩展实现的

public extension ConstraintView {
   
    public var snp: ConstraintViewDSL {
   
        return ConstraintViewDSL(view: self
    }
}

snp 最后是生成了一个 ConstraintViewDSL 对象
ConstraintView的定义

if os(iOS) || os(tvOS)
    public typealias ConstraintView = UIView
#else public
    typealias ConstraintView = NSView
#endif

       这里,tvOS是基于 iOS的操作系统,tvOS 是专门为第四代 Apple TV设计的操作系统。

ConstraintViewDSL

internal init(view: ConstraintView) {
   
     self.view = view 
}

ConstraintViewDSL 类的构造函数,就是将 view 保存起来

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

makeConstraints 函数将传进来的闭包传递给ConstraintMaker 这个类去处理了

internal static func makeConstraints(item: LayoutConstraintItem,closure: (_ make: ConstraintMaker) -> Void) {
   
     let constraints = prepareConstraints(item: item, closure: closure)
     for constraint in constraints {
   
         constraint.activateIfNeeded(updatingExisting: false)
    }
}

该方法主要调用了被接受preConstraints函数。

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
}

        首先这里构造一个 maker,然后调用闭包,闭包内部会添加一些约束,接下来就是获取这些约束, 最后将约束激活。
        闭包就是能够读取其他函数内部变量的函数。例如在程序中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

internal init(item: LayoutConstraintItem) {
   
    self.item = item
    self.item.prepare()
}

        这是ConstraintMaker的构造函数,这里出现了一个新的类型LayoutConstraintItem,表示一个可布局的对象,

public protocol LayoutConstraintItem: class {
   
}

可以看到这是一个协议

extension ConstraintLayoutGuide : LayoutConstraintItem {
   
}
extension ConstraintView : LayoutConstraintItem {
   
}

ConstraintView 和 ConstraintLayoutGuide 都实现LayoutConstraintItem这个协议。

extension LayoutConstraintItem {
   
    internal func prepare() {
   
     
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值