Swift - 自动布局库SnapKit的使用详解

Swift - 自动布局库SnapKit

来源:原文

为了适应各种屏幕尺寸,iOS 6后引入了自动布局(Auto Layout)的概念,通过使用各种Constraint(约束)来实现页面自适应弹性布局。(想了解更多可查看我原来写的这篇文章:Swift - 使用Auto Layout和Size Classes实现页面自适应弹性布局

在StoryBoard中使用约束实现自动布局很方便,但如果用纯代码来设置约束就很麻烦了。这里向大家推荐一个好用的第三方布局库:SnapKit(其前身是Masonry,一个OC版的布局库)

原文出自:www.hangge.com转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1097.html

例子:计算器

1,SnapKit介绍

SnapKit是一个优秀的第三方自适应布局库,它可以让iOS、OS X应用更简单地实现自动布局(Auto Layout)。

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

2,SnapKit配置

(1)将下载下来的SnapKit项目的SnapKit.xcodeproj拖进自己的项目目录当中

(2)在 工程 ->General->Embedded Binaries中点击加号,添加SnapKit库到项目中来

3.SnapKit的使用方法

通过snp.makeConstraints方法给view添加约束

约束:边距,宽,高,左右上下距离,基准线。

同时,添加过约束后可以修正,修正有位移修正(inset、offset)和倍率修正(multipliedBy)

语法一般是: make.equalTo 或 make.greaterThanOrEqualTo 或 make.lessThanOrEqualTo + 倍数和位移修正。

.equalTo:等于

.lessThanOrEqualTo:小于等于

.greaterThanOrEqualTo:大于等于

注意: 使用snp.makeConstraints方法的元素必须事先添加到父元素的中,例如:self.view.addSubview(view)


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

(1)width、height属性

自动布局允许宽度、高度设置为常量值。

make.height.equalTo(20)

make.width.equalTo(self.buttonSize.width)

//当前视图与label的顶部齐平

make.top.equalTo(label.snp.top)

(2)使用snp.updateConstraints更新约束

我们还可以用snp.updateConstraints方法来代替snp.makeConstraints进行约束的更新,这个更新操作通常放在UIViewController的updateViewConstraints()方法中,或者UIView的updateConstraints()方法中执行,这样视图约束需要更新的时候会自动调用。

比如下面样例,我们使用snp.updateConstraints()方法设置橙色视图的宽度约束为与屏幕等宽,这样不管设备如何旋转,视图都回自动更新约束撑满屏幕。

importUIKit

importSnapKit

classViewController:UIViewController{

lazyvarbox =UIView()

overridefuncviewDidLoad() {

super.viewDidLoad()

box.backgroundColor =UIColor.orange

self.view.addSubview(box)

box.snp.makeConstraints { (make) ->Voidin

make.width.equalTo(self.view)

make.height.equalTo(150)

make.centerX.equalTo(self.view)

}

}

//视图约束更新

overridefuncupdateViewConstraints() {

self.box.snp.updateConstraints{ (make) ->Voidin

//视图宽度与屏幕等宽

make.width.equalTo(self.view)

}

super.updateViewConstraints()

}

}


5、约束优先级

我们使用SnapKit的时候,还可以定义约束的优先级。这样当约束出现冲突的时候,优先级高的约束覆盖优先级低的约束。具体优先级可以放在约束链的结束处。

(1)优先级设置

通过priority()方法我们可以设置任意的优先级,接受的参数是0-1000的数字。比如:priority(600)。

如果不设置的话,默认的优先级是1000。

(2)使用优先级的样例

下面我们在屏幕中央放置一个100*100的橙色方块,给其定义了长宽尺寸小于等于屏幕的大小的默认优先级约束。同时,每次点击屏幕的时候,会更新放大它的尺寸。但由于这个约束的优先级是低,所有方块顶到屏幕边缘后就会不再放大。

importUIKit

importSnapKit

classViewController:UIViewController{

lazyvarbox =UIView()

varscacle = 1.0

overridefuncviewDidLoad() {

super.viewDidLoad()

//单击监听

lettapSingle=UITapGestureRecognizer(target:self,action:#selector(tapSingleDid))

tapSingle.numberOfTapsRequired=1

tapSingle.numberOfTouchesRequired=1

self.view.addGestureRecognizer(tapSingle)

box.backgroundColor =UIColor.orange

self.view.addSubview(box)

box.snp.makeConstraints { (make) ->Voidin

//视图居中

make.center.equalTo(self.view)

//初始宽、高为100(优先级低)

make.width.height.equalTo(100 *self.scacle).priority(250)

//最大尺寸不能超过屏幕

make.width.height.lessThanOrEqualTo(self.view.snp.width)

make.width.height.lessThanOrEqualTo(self.view.snp.height)

}

}

//点击屏幕

functapSingleDid(){

self.scacle += 0.5

self.box.snp.updateConstraints{ (make) ->Voidin

//放大视图(优先级最低)

make.width.height.equalTo(100 *self.scacle).priority(250)

}

}

}

2,带有动画效果

配合UIView.animate(withDuration: ),我们可以在约束改变的时候有动画效果。

还是以上面的样例演示,不够这次点击屏幕时橙色视图放大的时候会有过渡,而不是一下就变大。

importUIKit

importSnapKit

classViewController:UIViewController{

lazyvarbox =UIView()

varscacle = 1.0

overridefuncviewDidLoad() {

super.viewDidLoad()

//单击监听

lettapSingle=UITapGestureRecognizer(target:self,action:#selector(tapSingleDid))

tapSingle.numberOfTapsRequired=1

tapSingle.numberOfTouchesRequired=1

self.view.addGestureRecognizer(tapSingle)

box.backgroundColor =UIColor.orange

self.view.addSubview(box)

box.snp.makeConstraints { (make) ->Voidin

//视图居中

make.center.equalTo(self.view)

//初始宽、高为100(优先级低)

make.width.height.equalTo(100 *self.scacle).priority(250)

//最大尺寸不能超过屏幕

make.width.height.lessThanOrEqualTo(self.view.snp.width)

make.width.height.lessThanOrEqualTo(self.view.snp.height)

}

}

//视图约束更新

overridefuncupdateViewConstraints() {

self.box.snp.updateConstraints{ (make) ->Voidin

//放大尺寸(优先级低)

make.width.height.equalTo(100 *self.scacle).priority(250)

}

super.updateViewConstraints()

}

//点击屏幕

functapSingleDid(){

self.scacle += 0.5

//告诉self.view约束需要更新

self.view.setNeedsUpdateConstraints()

//动画

UIView.animate(withDuration: 0.3) {

self.view.layoutIfNeeded()

}

}

}

原文出自:www.hangge.com转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1114.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容