SnapKit简易教程

语言: swift, 版本:swift5,XCode:10.2
写作时间:2019-06-19

Introduction to SnapKit: Make Auto Layout Easy for iOS App Development

SnapKit简介

相对布局,Swift用SnapKit,跟Objc用Masonry是一个团队维护的,所以语法糖都一毛一样。github Star > 1.5w, 信得过!
SnapKit简易教程_第1张图片
Demo gif:
SnapKit简易教程_第2张图片

1. 相对于父容器的布局,80%场景都可解决

注意:设置相对布局之前,前置条件为把addSubview加入父视图

跟父界面的布局一毛一样,也就是逆时针方向上左下右,可以设置距离边界偏移量offset(上和左是用正数,下和右是用负数表示缩进), 设置优先级priority,默认是1000; 常用情况的subview的是3个方向跟父界面相对,缺少一个方向,用高度或者宽度定位:

		viewTop = UIView()
        viewContainer.addSubview(viewTop)
        
        viewTop.backgroundColor = innerViewBGColor
        viewTop.snp.makeConstraints { (make) in
        	make.top.equalTo(viewContainer).offset(40).priority(750)
            make.left.equalTo(viewContainer)
            make.bottom.equalTo(viewContainer)
            make.right.equalTo(viewContainer)
            //make.height.equalTo(100)
        }

如果跟父视图都一致,有内边距可以用UIEdgeInsets:

lblTitle.snp.makeConstraints { (make) in
            make.edges.equalTo(viewTop).inset(UIEdgeInsets(top: 0.0, left: 16.0, bottom: 0.0, right: 0.0))
        }

2. 保存约束条件Constraint,做动画的时候可以直接修改约束

保存约束self.centerYConstraint,实际上上面Y方向已经居中

func setupContainerView() {
        viewContainer = UIView()
        self.addSubview(viewContainer)
        
        viewContainer.snp.makeConstraints { (make) in
            self.centerYConstraint = make.centerY.equalTo(self).constraint
        }
    }

更新Y方向向下偏移10px:

centerYConstraint.update(offset: 10)

self.setNeedsLayout()

UIView.animate(withDuration: 0.4) {
    self.layoutIfNeeded()
}

3. 链式设计模式

上面为啥centerYConstraint跟make的用法一样? 这是链式设计模式,也就是left, top, centerY, 等方法返回都是self自己。比如left, top都是跟父视图一样,也可以这么写:

        viewTop.snp.makeConstraints { (make) in
        	make.left.top.equalTo(viewContainer)
        	// the same as below
        	// make.left.equalTo(viewContainer)
        	// make.top.equalTo(viewContainer)
        }

看源码是如何使用链式设计模式的:

public var left: ConstraintMakerExtendable {
    self.description.attributes += .left
    return self
}

public var top: ConstraintMakerExtendable {
    self.description.attributes += .top
    return self
}

public var bottom: ConstraintMakerExtendable {
    self.description.attributes += .bottom
    return self
}

public var right: ConstraintMakerExtendable {
    self.description.attributes += .right
    return self
}

4. 4. 重新设置约束remakeConstraints

清空原有约束,重新定义约束用remakeConstraints:

txtEmail.snp.remakeConstraints { (make) in
     make.top.equalTo(viewTop.snp.bottom).offset(16)
     make.left.equalTo(viewContainer).offset(8)
     make.right.equalTo(viewContainer).offset(-8)
     make.height.equalTo(textfieldHeight)
 }

5. 5. 更新已经存在的约束

如果原有约束存在,需要更新约束 updateConstraints:

activityIndicator.snp.updateConstraints { (make) in
    make.centerY.equalTo(viewContainer).offset(-containerViewHeight/2 - 20)
}

6. 为啥不会循环引用

view自己调用的方法,方法中的参数make又是自己,为啥不会循环引用

btnConnect.snp.makeConstraints { (make) in
    make.top.equalTo(viewBottom)
    make.right.equalTo(viewBottom)
    make.bottom.equalTo(viewBottom)
    make.width.equalTo(connectButtonWidth)
}

看源码可以知道端倪,方法中的block没有被self引用,也就不会存在循环引用。

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

7. 总结

SnapKit 用第一节的方法可以解决80%的常见布局功能,有动画需求参照下面的3个小节也可以解决。完整教程请参照:Introduction to SnapKit: Make Auto Layout Easy for iOS App Development

代码下载

https://github.com/zgpeace/SnapkitDemo

参考

https://www.appcoda.com/snapkit/
https://github.com/SnapKit/SnapKit
https://github.com/SnapKit/Masonry

你可能感兴趣的:(iOS)