SnapKit-自动布局库学习笔记

SnapKit-自动布局库学习笔记

本文介绍快速上手指南,想100%掌握移步别的教程


大体使用方法

  • 1、初始化子视图(不需要frame参数),addSubview到父视图上
  • 2、调用 subView.snp.makeConstraints { make in … }

    尽情享受简洁代码实现 AutoLayout吧!

_UIView.snp.makeConstraints 方法给view添加约束,约束种类 常用的:centerX/Y,宽,高,上下左右距离。同时,添加过约束后可以有修正(inset、offset)//其他不常用的以后再说

约束条件参数

读下面的代码,就可以直接上手用了

import UIKit
import SnapKit
//例一
class ViewController: UIViewController {

    var box = UIView()

    override func viewDidLoad() {
        super.viewDidLoad() 

        box.backgroundColor = UIColor.orange
        view.addSubview(box)

        box.snp.makeConstraints { make in
            make.width.equalTo(100)
            make.height.equalTo(100)
            make.center.equalTo(self.view)
            //笔记一:如果参数是一个UIView或其子类,就相当于view.snp.center
            //前面是center就省略的 snp.center,前面是width就省略的 snp.width
        }
    }
}

//例二
class ViewController2: UIViewController {

    var box = UIView()
    override func viewDidLoad() {
        super.viewDidLoad()         
        box.backgroundColor = UIColor.orange
        self.view.addSubview(box)  

        box.snp.makeConstraints { make in           
            make.width.height.equalTo(100)
            //笔记二:可以 宽 高等等属性 串联用,像上面这句
            make.center.equalTo(self.view)
        }
    }
}


一、所有属性(很多不常用)

视图属性(ViewAttribute)布局属性(NSLayoutAttribute)
view.snp.leftNSLayoutAttribute.Left
view.snp.rightNSLayoutAttribute.Right
view.snp.topNSLayoutAttribute.Top
view.snp.bottomNSLayoutAttribute.Bottom
view.snp.leadingNSLayoutAttribute.Leading
view.snp.trailingNSLayoutAttribute.Trailing
view.snp.widthNSLayoutAttribute.Width
view.snp.heightNSLayoutAttribute.Height
view.snp.centerXNSLayoutAttribute.CenterX
view.snp.centerYNSLayoutAttribute.CenterY
view.snp.baselineNSLayoutAttribute.Baseline

二、视图关系(不常用,可跳过)

想让view.left 大于等于 label.left:
make.left.greaterThanOrEqualTo(label)
像刚才说的,它就等价于:
make.left.greaterThanOrEqualTo(label.snp.left)

三、确定值 (常用)

比如将宽度和高度属性设置为常量值:(常量值根据设备不同适配不同的值)

make.height.equalTo(20)
make.width.equalTo(20)
make.top.equalTo(42)


给视图的各种属性设置约束

直接看代码

class ViewController: UIViewController {

    //外部方块
    var boxOutter = UIView()
    //内部方块
    var boxInner = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        boxOutter.backgroundColor = UIColor.orange
        view.addSubview(boxOutter)

        boxInner.backgroundColor = UIColor.green
        boxOutter.addSubview(boxInner)

        boxOutter.snp.makeConstraints { make in
            make.width.height.equalTo(200)
            make.center.equalTo(self.view)
        }

         //注意两个view是嵌套的
        boxInner.snp.makeConstraints { make in
            make.width.height.equalTo(100)
            make.right.equalTo(0)
            make.bottom.equalTo(0)
        }
        /* 
        box2.snp.makeConstraints { make in
            make.width.height.equalTo(box1)
            make.left.equalTo(box1)
            make.top.equalTo(box1.snp.bottom)
        }
        */
    }
}

edges(边缘)

(先说下偏移,一会见到:offset多少 是往右或往下或往外多少,inset相反)

让当前视图 的 上下左右(top,left,bottom,right) 等于 view2
make.edges.equalTo(view2)
// 内偏移
make.edges.equalTo(view2).inset(UIEdgeInsetsMake(10, 15, 20, 25))
// 外偏移
make.top.equalTo(view2).offset(20)

size(尺寸)

// 外偏移 -50,就是内移。。
make.size.equalTo(boxOutter).offset(-50)
//size就是让 width = 父视图.width - 50, height = 父视图.height - 50

center(中心)

当前视图与 button1中心相同 (centerX 和 centerY)
make.center.equalTo(button1)

//倍率:multipliedBy 将视图的尺寸设置成父视图几倍大小,乘法
make.center.equalTo(boxOutter)
make.size.equalTo(boxOutter).multipliedBy(0.5)
//即 width = superview.width * 0.5, height = superview.height / 2

修改约束

我们可以通过 约束的引用 来修改约束。

删除

开始我们给方块添加宽高150约束,以及页面居中约束,然后另点一个击按钮调用其 deactivate() 方法把这尺寸约束给移除,方块消失(即长宽变成0,0) demo:

import UIKit
import SnapKit
class ViewController: UIViewController {
    var box = UIView()
    //声明一个约束的引用
    var sizeConstraint:Constraint?

    override func viewDidLoad() {
        super.viewDidLoad()    
        box.backgroundColor = UIColor.orange
        self.view.addSubview(box)

        box.snp.makeConstraints { (make)  in
            self.sizeConstraint = make.width.height.equalTo(150).constraint
            //上句解释:在把宽高设为150同时,把约束赋值给那个变量

            make.center.equalTo(self.view)
        }
    }   
    //按钮点击
    @IBAction func btnTouch(_ sender: AnyObject) {
        //移除约束
        self.sizeConstraint?.deactivate() 
        //相反:sizeConstraints?.activate()

        /*注意:这个方法是针对宽高的约束,如果是下面这样位置的约束就没反应:
        make.width.height.equalTo(100)
        sizeConstraints = make.left.top.equalTo(100).constraint
        下面关于更新约束的内容会涉及。
        */
    }
}

更新

把 make 修改为:

        make.width.height.equalTo(150) //大小
        make.centerX.equalTo(self.view) // x轴方向,下面y轴方向:
        myConstraint = make.top.equalTo(self.view).offset(40).constraint

把按钮事件内容修改为:

myConstraint?.update(offset: 60) //把offset设置为60,不是加60;参数可以是inset,原理相同。


snp的其他方法

前面我们只用到了 snp.makeConstriants ,下面是其他几个方法及用途:


snp.updateConstraints

更新某项约束。应用:转屏 自动设置和屏幕等宽

class ViewController: UIViewController {     
    var box = UIView()    
    override func viewDidLoad() {
        super.viewDidLoad()      
        box.backgroundColor = UIColor.orange
        self.view.addSubview(box)

        box.snp.makeConstraints { (make) in
            make.width.equalTo(self.view)
            make.height.equalTo(150)
            make.centerX.equalTo(self.view)
        }
    }
    //视图约束更新,在 1、界面将出现时 2、转屏时 自动调用。
    override func updateViewConstraints() {
        self.box.snp.updateConstraints{ (make) in
            make.width.equalTo(self.view)
        }
        super.updateViewConstraints() //文档里让一定要最后写上这句==
    }
    //注意!界面显示时一定会调用该方法来重新设置width,但是在上面 makeConstraints里必须设置width,不然等崩(snp库自报fatalError)
    //但是如果没有重写这个update方法,就可以不设置width,并默认为0(没有人会不去设置的对吧)==
}

snp.remakeConstraints

//三分钟 remake了

snp.remakeConstraints 首先会先清除掉之前所有被SnapKit设置的约束。比如你点击某个按钮,响应里调这个方法。其他用法完全同makeConstraints.

约束优先级

优先级高的约束覆盖优先级低的约束(看demo就明白)
通过 priority() 方法,参数是0-1000的数字,默认优先级1000
        box.snp.makeConstraints { (make) in
            make.center.equalTo(self.view) //居中

            make.width.height.equalTo(200).priority(250) //250级
            make.width.lessThanOrEqualTo(100) //1000级!
            make.height.lessThanOrEqualTo(100).priority(200) //200级
            make.height.lessThanOrEqualTo(100).priority(250) //250级,同样级数比谁定义的早
            //结果宽高分别是: 100200
        }

约束改变时配动画效果

demo

import Foundation
import UIKit
import SnapKit

class SignInViewController: UIViewController {

    var box = UIView()
    var scale = 1.0

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.white
        box.backgroundColor = UIColor.lightGray

        //使用 snp.makeConstraints 方法必须先添加到父视图
        view.addSubview(box)

        box.snp.makeConstraints{ (make) in
            make.width.equalTo(100)
            make.top.height.equalTo(100)
        }

        box.isUserInteractionEnabled = true
        let gesture = UITapGestureRecognizer(target: self, action: #selector(onTap))
        box.addGestureRecognizer(gesture)


    }
    override func updateViewConstraints() {
        print("updating")
        box.snp.updateConstraints{ (make) in
            make.width.equalTo(100*scale)
        }
        super.updateViewConstraints()
        print("updated")
    }

    func onTap(){
        scale += 0.5
        view.setNeedsUpdateConstraints()
        print("needed")
        UIView.animate(withDuration: 0.5){
            print("start animating")
            self.view.layoutIfNeeded() // mark1
            print("start sleeping")
            //Thread.sleep(forTimeInterval: 2) //mark2
            print("stop animating")
        }
        print("func end")
    }
}

先解释几个方法:

setNeedsUpdateConstraints()

声明 view 处于 需要更新约束的状态。注意是声明。到底什么时候开始更新呢?看下面

layoutIfNeeded()

如果view处于 需要布局的状态,就立刻开始布局 ( 调用updateViewConstraints() )

如果 setNeedsUpdateConstraints() 所处的代码块 { } 内代码全都执行完了还没遇见 layoutIfNeeded() 指令,就开始执行updateViewConstraints()

现在 把 mark2 那行注释去掉,跑两遍:
mark1 那行注释掉与不注释掉分别跑一遍,看打印就能理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值