Swift自动布局篇之Snapkit简单使用

Swift自动布局篇之Snapkit简单使用

Aron Lv3

SnapKit可以认为是Masonry的Swift版本,本文介绍以及实例如何使用SnapKit进行AutoLayout编程

Swift导入:

1),通过cocoapdos安装,如果不会用cocoapods的话可以去看看code4app的这篇博客
Podfile配置如下:

1
2
3
4
5
platform :ios, '8.0'
use_frameworks!
target '你的工程名称' do
pod 'SnapKit'
end

2),直接将SnapKit拖进工程目录,到SnapKit的Github点击Download Zip按钮下载SnapKit工程文件,解压后把其中的SnapKit.xcodeproj文件直接拖进工程即可.切记确保SnapKit工程下的所有需要的支持文件全都被拖过去了.(SnapKit工程本身不支持iOS7或之前的系统,如果需要支持iOS7的话请考虑此方法导入.)

简单使用

举个小栗子

1
2
3
4
5
6
        let redView = UIView()
        redView.backgroundColor = UIColor.redColor()
        self.view.addSubview(redView)
        redView.snp_makeConstraints { (make) in
            make.edges.equalTo(self.view).inset(UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))//将redView的边界约束为self.view并且每条边都是20的偏移
        }

效果图:

效果图1
效果图1

当然,完全支持横屏,我这里就不放图片了.
与上面使用的edges相似的其他属性:
边界: left,right,top,bottom,edges,leading,trailing
(left与leading的区别,left始终代表view的左边,而leading代表view的布局起点,如果是从左到右布局则代表view的左边,其他的以此类推)
尺寸,大小:width,height,size
(如果需要在.equalTo或其他函数中使用这些属性,则要使用其对应的snp_top,snp_bottom…..版本)
优先级:priority,一般用在约束语句链的最后面,例如

1
2
make.bottom.equalTo(self.view).priorityLow()//低优先级
//也可以使用priority()方法传入具体优先级的级别,(0-1000)

与equalTo相似的其他约束函数:
小于等于:lessThanOrEqualTo
大于等于:greaterThanOrEqualTo
我最经常使用lessThanOrEqualTo或者greaterThanOrEqualTo是针对于UILabel的约束,如果有这么个需求:文字长度如果短于某个值,则让label适应文字宽度,如果长于这个值的话,则让label的宽度固定,高度适应其文本,那么这里的”小于等于”就派上用场了,看代码:

1
2
3
4
5
6
7
        self.label.text = "这是一个很长的字符串"
self.label.numberOfLines = 0
        self.view.addSubview(self.label)
        label.snp_makeConstraints { (make) in
            make.center.equalTo(self.view)
            make.width.lessThanOrEqualTo(self.view).offset(-50)//只需要约束宽度即可,这里约束的最大宽度为屏幕宽度-50,事实上如果没有其他需求的话针对于一个label来说只需要确定一个位置,不需要大小就可以认定这是一个完整的约束.(此技能目前我只知道针对于UILabel,UIImageView,UIButton有效)
        }

然后我们在控制器的touchesBegan里面这么写

1
            self.label.text! += self.label.text!

在初始状态的label:

多点几下就是这样

约束更新&重做约束:

  • SnapKit内置snp_updateConstraints方法用来更新约束.其内部写法与加约束的方式一致,需要注意的是,所谓的更新也就意味着砸原有的基础上进行修改,所以说更新约束必须要和加约束的时候相对应,比如说你在snp_makeConstraints中给一个View加了一个针对于center的约束,在更新约束时就只能修改针对于这个center的约束,否则的话你只能得到一个警报
  • 重做约束,snp_remakeConstraints,这个理解起来就很简单了,实现这个方法之后会移除view之前所有的约束然后重新添加约束.
    (更新约束之后如果需要立即体现出来的话,可以先对更新约束的父View调用setNeedsLayout()使父view进入需要更新布局的状态,其次再layoutIfNeeded()更新布局,如果需要动画的话,把layoutIfNeeded()放到动画过程里面即可)
SnapKit中没有类似于Masonry中的给一组View进行约束的方法.

一些小Tips

对于在UIScrollView上使用自动布局,scrollView的子视图务必四周都对scrollView进行约束,原因很简单:scrollView的滑动是依赖其属性contentSize,如果这个size小于scrollView视图本身的话就不能滑动,添加子视图的时候对四周做约束就相当于把contentSize”撑”开了,帮助其确定子控件也就是其contentSize大小.

一个比较常用的做法是,给ScrollView添加一个子View作为其contentView,给contentView的四周针对ScrollView添加约束,然后其他控件添加在contentView之内.这个方式不管是代码布局还是使用故事板都同样适用.

对于一个Autolayout Based View,如何计算其本身的实际内容大小?

1
2
3
// UIView用于计算其内容大小的api,需要注意的是如果希望得到正确的结果,需要确保所有的subView之间的约束,可用于确定当前View的大小。
func systemLayoutSizeFitting(_ targetSize: CGSize) -> CGSize
// 参数分别传入`UILayoutFittingExpandedSize`或者`UILayoutFittingCompressedSize`可用于获得其最大的可能大小或者最小的可能大小(一般来说就是内容实际占用的大小)。

AutoLayout针对于UILabel,UIImageView,UIButton来说,只需要确定其位置(x轴与y轴),便可以算是一个完整的约束,不同的是UILabel会根据其文字内容来确定控件大小,UIButton在没有标题的情况下同样如此,UIImageView以及设置了image的UIButton,一般会根据图片的大小来确定控件大小,所以对于带image的button以及UIImageView来说,最好还是要加上针对于四周的约束.
补充一点,有时候我们的需求是,不管是横屏还是竖屏,View刚好在导航栏下面,我们都知道导航栏加上状态栏是64的高度,而横屏状态下是没有状态栏的,针对这一点其实Masonry还有SnapKit都有针对这种情况的解决方案.在SnapKit的UIViewController+SnapKit.swift文件中,给UIViewController加了这样几个属性
snp_topLayoutGuideTop//顾名思义,这里的topLayoutGuide一般指的是导航栏
snp_topLayoutGuideBottom
snp_bottomLayoutGuideTop//这里的bottomLayoutGuide一般指的是Tabbar
snp_bottomLayoutGuideBottom
那么guideTop,guideBottom就是针对导航栏或者tabbar的顶部与底部

  • 标题: Swift自动布局篇之Snapkit简单使用
  • 作者: Aron
  • 创建于 : 2016-05-22 20:42:17
  • 更新于 : 2025-10-14 09:29:25
  • 链接: https://likeso.github.io/2016/05/22/snapkit-usage/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论