snapkit_snapkitsample-android - CSDN
  • SnapKit简易教程

    2019-07-03 12:30:08
    Introduction to SnapKit: Make Auto Layout Easy for iOS App Development SnapKit简介 相对布局,Swift用SnapKit,跟Objc用Masonry是一个团队维护的,所以语法糖都一毛一样。 Demo gif: 1. 相对于父...

    语言: 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, 信得过!
    在这里插入图片描述
    Demo gif:

    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

    展开全文
  • 大家都知道在OC当中的三方布局Masnory,而到swift中大家想用masnory会有很多不便之处,随之而来的是SnapKit其实是和masonry是孪生兄弟。GtiHub地址:https://github.com/SnapKit/SnapKit直接把source目录下的文件拉...

    大家都知道在OC当中的三方布局Masnory,而到swift中大家想用masnory会有很多不便之处,随之而来的是SnapKit其实是和masonry是孪生兄弟。

    GtiHub地址:https://github.com/SnapKit/SnapKit


    直接把source目录下的文件拉到项目中去即可使用。

    使用方法如下:大致跟masonry相似。

            let line = UIView()

            line.backgroundColor = UIColor.lightGray

            self.addSubview(line)

            line.snp.makeConstraints { (make) in

                make.bottom.equalToSuperview()

                make.left.equalToSuperview()

                make.right.equalToSuperview()

                make.height.equalTo(1)

            }


    展开全文
  • SnapKit 是在iOS开发中使用添加约束的纯代码库. 使用Swift语言进行编写. 作为有一定经验的人, 对Masonry应该不陌生. 像Masonry一样. 在同一个仓库中 0.O 屏幕快照 2016-05-17 16.25.59.png var redView = ...

    前言: 今天介绍的是一个三方库. SnapKit 是在iOS开发中使用添加约束的纯代码库. 使用Swift语言进行编写. 作为有一定经验的人, 对Masonry应该不陌生. 像Masonry一样. 在同一个仓库中 0.O


    屏幕快照 2016-05-17 16.25.59.png
        var redView      = UIView()
        var yellowView   = UIView()
        var greenView    = UIView()
        var blackView    = UIView()
        var purpleView   = UIView()
        var cyanView     = UIView()
        var grayViewBtn  = UIButton()
        var leftView     = UIView()
        var rightView    = UIView()

    在viewdidload中进行一些设置

            redView.backgroundColor = UIColor.redColor()
            yellowView.backgroundColor = UIColor.yellowColor()
            greenView.backgroundColor = UIColor.greenColor()
            blackView.backgroundColor = UIColor.blackColor()
            purpleView.backgroundColor = UIColor.purpleColor()
            cyanView.backgroundColor = UIColor.cyanColor()
            grayViewBtn.backgroundColor = UIColor.grayColor()
            leftView.backgroundColor = UIColor.cyanColor()
            rightView.backgroundColor = UIColor.orangeColor()
            // 添加
            view.addSubview(redView)
            view.addSubview(yellowView)
            view.addSubview(greenView)
            view.addSubview(blackView)
            view.addSubview(purpleView)
            view.addSubview(cyanView)
            view.addSubview(grayViewBtn)
            view.addSubview(leftView)
            view.addSubview(rightView)
            grayViewBtn.setTitle("PopLabel", forState: UIControlState.Normal)
            grayViewBtn.addTarget(self, action: #selector(ViewController.clcik), forControlEvents: UIControlEvents.TouchUpInside)
            // 进行约束
            blackView.snp_makeConstraints { make in
                make.center.equalTo(view)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            }
    
            redView.snp_makeConstraints { make in
                make.top.equalTo(blackView.snp_bottom).offset(20.0)
                make.left.equalTo(20.0)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            }
    
            yellowView.snp_makeConstraints { make in
                make.top.equalTo(blackView.snp_bottom).offset(20.0)
                make.left.equalTo(blackView.snp_right).offset(20.0)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            }
    
            purpleView.snp_makeConstraints { make in
                make.bottom.equalTo(blackView.snp_top).offset(-20.0)
                make.left.equalTo(blackView.snp_right).offset(20.0)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            }
    
            greenView.snp_makeConstraints { make in
                make.bottom.equalTo(blackView.snp_top).offset(-20.0)
                make.right.equalTo(blackView.snp_left).offset(-20.0)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            }
            // cyan
            cyanView.snp_makeConstraints(closure: { (make) in
                make.top.equalTo(redView.snp_bottom).offset(20.0)
                make.centerX.equalTo(view)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            })
            // gray
            grayViewBtn.snp_makeConstraints(closure: { (make) in
                make.bottom.equalTo(greenView.snp_top).offset(-20.0)
                make.centerX.equalTo(view)
                make.size.equalTo(CGSizeMake(100.0, 100.0))
            })
            //
            leftView.snp_makeConstraints(closure: { (make) in
                make.top.equalTo(greenView.snp_bottom).offset(20.0)
                make.bottom.equalTo(redView.snp_top).offset(-20.0)
                make.left.equalTo(view.snp_left).offset(5)
                make.width.equalTo(50)
            })
    
            rightView.snp_makeConstraints(closure: { (make) in
                make.top.equalTo(purpleView.snp_bottom).offset(20.0)
                make.bottom.equalTo(yellowView.snp_top).offset(-20.0)
                make.right.equalTo(view.snp_right).offset(-5)
                make.width.equalTo(leftView)
            })


    展开全文
  • 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.left NSLayoutAttribute.Left
    view.snp.right NSLayoutAttribute.Right
    view.snp.top NSLayoutAttribute.Top
    view.snp.bottom NSLayoutAttribute.Bottom
    view.snp.leading NSLayoutAttribute.Leading
    view.snp.trailing NSLayoutAttribute.Trailing
    view.snp.width NSLayoutAttribute.Width
    view.snp.height NSLayoutAttribute.Height
    view.snp.centerX NSLayoutAttribute.CenterX
    view.snp.centerY NSLayoutAttribute.CenterY
    view.snp.baseline NSLayoutAttribute.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 那行注释掉与不注释掉分别跑一遍,看打印就能理解了。

    展开全文
  • SnapKit使用详解

    2017-05-30 11:01:30
    SnapKit使用详解
  • SnapKit的简介

    2018-10-31 17:11:30
    https://www.jianshu.com/p/2bad53a2a180
  • SnapKit配置过程记录

    2016-07-13 16:25:54
    SnapKit是大名鼎鼎的Masonry的Swift版本,主要是能让开发者在iOS和OS X上更简单地进行Auto Layout的DSL。
  • snapkit

    2019-05-06 20:58:19
    snapkit https://www.jianshu.com/p/f2aba4796463 $0.left.right.bottom.top.equalToSuperview() 和父view相等 make.left.equalToSuperview().offset(15) 和父view比较,有15的边距 $0.height.equalTo(250) ...
  • SnapKit 一个用于iOS和OS X的Swift Autolayout DSL
  • SnapKit这个第三方写自动布局,使用起来的确很舒服,但是对于Array却没有相关的支持,然后在网上找了这篇文 SnapKit的扩展–添加数组控制约束,和九宫格布局,等宽,等间距等布局方式 但是只有水平、垂直、九宫格...
  • SnapKit - 修改约束

    2018-05-14 18:27:14
    AutoLayout现在是iOS开发布局的必备,对于使用Swift语言开发的项目,我们经常使用SnapKit进行UI布局,因为使用简单,方便。基本的使用方法官方已经写的非常详情了,可以看这里。官方为我们提供了几种方式来修改约束...
  • SnapKit,一个经典的Swift版的第三方库,专门用于项目的自动布局,目前在github上的stars就高达9340颗星,这是一个不小的数字,亦足以证明它存在的非凡意义和作用。作者认为,在iOS开发(swift)中,它是用于项目最...
  • 一直觉得 SnapKit 和 Masonry 这两个框架设计和封装的很好,用起来的体验也是一致的,翻了下它们的源码,对其设计方式和涉及的技术做了下记录。文章打算围绕,给谁做约束?如何设置约束?设置完后如何处理?这三个...
  • SnapKit

    2016-09-04 00:31:09
    SnapKit SnapKit 是 Masonry 框架的团队针对 Swift 全新开发的一套自动布局框架 官方网站:http://snapkit.iogithub网站:https://github.com/SnapKit/SnapKit 文档地址:http://snapkit.io/docs/ ...
  • 其实也是可以导入自身工程的,只不过之前的方法不对,snapkit.xcoeproj拖入工程,然后点击根目录,然后点击build phase 这时添加的方式就相同了 ---------------------------------------------------------------...
  • iOS中SnapKit动画的实现

    2018-01-03 10:02:36
    在做项目的过程中突然遇到要在keywindow上添加一个全屏View...我突然想到了用SnapKit这个自动布局库来实现一下试试,经历了好几个版本的实验都以失败而告终,不是没有动画就是动画效果不对,总结了一下失败的原因主要有
  • Snapkit:https://github.com/SnapKit/SnapKit 一、约束UILabel这个其实本来是很简单的,被自己搞的复杂了,当设置UILabel的时候frame:CGRect.zero就可以了,另外行数设置为:0,一定一定不要设置固定高度 /(ㄒoㄒ)/~...
  • SnapKit 1 安装 SnapKit github地址 // // ViewController.swift // SK_SnapKit // // Created by coder on 2019/3/6. // Copyright © 2019 AlexanderYeah. All rights reserved. // import UIKit ...
  • SnapKit布局注意事项Snapkit简单布局Demo常见问题一:updateConstraints常见问题二:snapkit更改布局动画效果常见问题三:两个自适应宽度控件,导致右边的自适应问题 Snapkit SnapKit,一个经典的Swift版的第三方...
  • 在之前的文章中我介绍了如何使用SnapKit的 snp_makeConstraints 方法进行各种约束的设置。但有时我们的页面并不是一直固定不变的,这就需要修改已经存在的约束。本文介绍如何更新、移除、代替现有的约束。1,删除...
1 2 3 4 5 ... 20
收藏数 2,074
精华内容 829
关键字:

snapkit