StackView

我的博客, 各位看官有时间赏光

UIStackView

UIStackView介绍

随着autolayout的推广开来,更多的app开始使用自动布局的方式来构建自己的UI系统,autolayout配合storyBoard和一些第三方的框架,对于创建约束来说,已经十分方便,但是对于一些动态的线性布局的视图,我们需要手动添加的约束不仅非常多,而且如果我们需要插入或者移除其中的一些UI元素的时候,我们又要做大量的修改约束的工作,UIStackView正好可以解决这样的问题。

UIStackViewiOS 9 中新增的一个控件,它继承于UIView,用来管理一行或一列视图的布局(堆叠视图的控制器类视图,所谓堆叠视图时一种平铺式的线性布局方式,不可重叠,布局方向也不可交错)。UIStackView新增了几个属性,这些属性就是子视图布局规则。一旦UIStackView的这些属性发生变化,它的arrangedSubviews就会按照规则重新排布。只要我们掌握这些规则,就可以管理视图布局了。如果能再稍加灵活运用,有时候我们甚至能轻松实现一些精妙布局。 UIStackView可以帮助开发者更加简单的使用layout而不必手动添加太多布局约束.

属 性 作 用
Axis 属性决定了 stack 的朝向,只有垂直或水平
distribution 属性决定了其管理的视图在沿着其轴向上的布局
Alignment 属性决定了其管理的视图在垂直于其轴向上的布局
Spacing 属性决定了其管理的视图间的最小间隙
layoutMarginsRelativeArrangement 属性决定了 stack 视图平铺其管理的视图时是否要参照它的布局边距
baselineRelativeArrangement 属性决定了 stack 视图平铺其管理的视图时是否要参照它的布局边距

![Uploading 19_081418.png . . .]
](http://upload-images.jianshu.io/upload_images/1129706-a300c78a3ddc0cdb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

UIStackViewDistribution

axisspacingdistributionalignment是比较重要的4个属性,他们都能给布局带来明显的变化。axisspacing属性作用单一,通过属性解释或者通过视图简单观察我们就能理解他们的作用。distributionalignment这两个属性相对而言更具灵活性,也更具有难度,尤其是二者的结合使用。

public enum UIStackViewDistribution : Int {
  case fill
  case fillEqually
  case fillProportionally
  case equalSpacing
  case equalCentering
}

public enum UIStackViewAlignment : Int {
  case fill   
  case leading
  public static var top: UIStackViewAlignment { get }
  case firstBaseline
  case center
  case trailing
  public static var bottom: UIStackViewAlignment { get }
  case lastBaseline 
}
  • UIStackViewDistributionFill

将arrangedSubviews填充满整个StackView,他们之间的间隙等于spacing大小

如果减去所有的spacing,所有arrangedSubview的固有尺寸(intrinsicContentSize)之和不能填满StackView,那么就按照Hugging的优先级将其拉伸。反之,如果超出StackView的尺寸则按CompressionResistance的优先级压缩。如果优先级相同,就按排列顺序来拉伸或压缩。

Hugging/CompressionResistance.png

UIStackViewDistributionFill.png
  • UIStackViewDistributionFillEqually

每个arrangedSubview沿axis方向的长度相等,等于StackView沿axis长度减去spacing之和除以arrangedSubviews个数。

UIStackViewDistributionFillEqually.png
  • UIStackViewDistributionFillProportionally

    根据arrangedSubview的intrinsicContentSize,将StackView沿axis方向的长度减去spacing之和按比例分配给arrangedSubviews。

UIStackViewDistributionFillProportionally.png
  • UIStackViewDistributionEqualSpacing

    先按arrangedSubviews的intrinsicContentSize布局,然后余下的空间均分为spacing

    如果spacing小于StackView设置的spacing,则按照CompressionResistance的优先级来压缩arrangedSubviews。

UIStackViewDistributionEqualSpacing.png
  • UIStackViewDistributionEqualCentering

    令arrangedSubviews的中心点之间的距离相等,且spacing大于等于StackView设置的spacing(每两个arrangedSubview之间的spacing可能不相等)

    如果spacing小于StackView设置的spacing,则按照CompressionResistance的优先级来压缩arrangedSubviews。

UIStackViewDistributionEqualCentering.png

UIStackViewalignment

  • UIStackViewAlignmentFill

    在StackView轴向的垂直方向上拉伸所有子view来填充StackView

UIStackViewAlignmentFill.png
  • UIStackViewAlignmentLeading

    用于stackview是垂直轴向时,所有子view靠左对齐

UIStackViewAlignmentLeading.png
  • UIStackViewAlignmentTop

    用于stackview是水平轴向时,所有子view靠顶部对齐

UIStackViewAlignmentTop.png
  • UIStackViewAlignmentCenter

    在StackView轴向的垂直方向上子视图以中线为基准对齐

UIStackViewAlignmentCenter.png
  • UIStackViewAlignmentTrailing

    用于stackview是垂直轴向时,所有子view靠右对齐

UIStackViewAlignmentTrailing.png
  • UIStackViewAlignmentBottom

    用于stackview是水平轴向时,所有子view靠底部对齐

UIStackViewAlignmentBottom.png
  • UIStackViewAlignmentFirstBaseline

    用于stackview是水平轴向时,按照第一个子视图中文字的第一行对齐

UIStackViewAlignmentFirstBaseline.png
  • UIStackViewAlignmentLastBaseline

    用于stackview是水平轴向时,按照最后一个子视图中文字的最后一行对齐

UIStackViewAlignmentLastBaseline.png

storyboard添加StackView

  • IB
  • 从对象库中拖拽UIStackView到storyboard中,然后往内部扔控件(UIView或其子类)就可以了。
  • 选择storyboard中的控件,可以用“command键 + 单击”进行多选,然后点击下方的stack按钮,这样选中的控件就会被放入一个StackView中。
storyboard.png

代码添加StackView

  • 创建UIStackView
    UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:@[forkingLabel, logoImageView, dogLabel]];
    stackView.translatesAutoresizingMaskIntoConstraints = NO;
    stackView.axis = UILayoutConstraintAxisHorizontal;
    stackView.distribution = UIStackViewDistributionFill;
    stackView.alignment = UIStackViewAlignmentCenter;
    stackView.spacing = 0;
   [self.view addSubview:stackView];
  • 动态的改变其中view的个数
UIView * newView = [[UIView alloc]init];
[stackView addArrangedSubview:newView];

特别注意addArrangedSubviewaddSubview有很大的区别,使用前者是将视图添加进StackView的布局管理,后者只是简单的加在视图的层级上,并不接受StackView的布局管理。

  • 与之相对,我们可以使用下面的方法移除一个view
UIView * view = [stackView arrangedSubviews].lastObject;
[stackView removeArrangedSubview:view];

StackView使用技巧

  • 嵌套 只要嵌套好UIStackView,就可以用很少的约束达到自动布局界面的目的

使用StackView 嵌套 模仿同程首页布局

嵌套_TC.png

嵌套.png

  • 结合sizeClass 多屏幕适配
查看SatckView的Attributes Inspector,我们会发现StackView的几个主要属性都是可以设置sizeclass模式的,
这对我们的屏幕适配将会大有助益。再加上约束的sizeClass,灵活性可以想象。
多屏幕适配.png
  • 因为StackView继承于UIView,因此在布局改变的时候,我们可以使用UIView层的动画 添加view的时候会有动画效果,移除的时候没有
[stackView addArrangedSubview:newView];
[UIView animateWithDuration:1 animations:^{
[stackView layoutIfNeeded];
}];

stackView_gif.gif

FDStackView

UIStackView是在iOS9才推出的,最低支持的系统也是iOS9, FDStackView出现了,它就是为了解决UIStackView在低于iOS9的系统下无法使用的问题
FDStackView之前也已经有了一些类似的开源项目,比如OAStackViewTZStackView,然而他们都不能满足我们的需求,局限性还是比较大的,比如不支持IB,某些功能还没有实现,类名需要使用非UIStackView,在我们看来这些对开发者来说都是不友好的,开发者需要的是一款功能完善,支持IB,使用时完全无感,在Xcode7上直接使用UIStackView即可,接下来的事情交给FDStackView就好,它负责将UIStackView在低于iOS9的系统上运行。

需要注意如果使用IB的话,那么IBBuilds for属性需要设置为iOS 9.0 and later

FDStackView.png

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

推荐阅读更多精彩内容

  • StackView们 UIStackView是iOS9新引入的控件。它支持垂直和水平排列多个子视图(SubView...
    取水阅读 5,278评论 1 11
  • StackView学习 自适应、适配、布局这几个关键词一直伴随着iOS开发,从以前的单一尺寸屏幕,到现在的多尺寸屏...
    simuty阅读 1,144评论 4 2
  • UIStackView 类提供了一个高效的接口用于平铺一行或一列的视图组合。Stack视图使你依靠自动布局的能力,...
    Chivalrous阅读 680评论 1 2
  • 前言 首先,我们通过下面这张图片引出今天的主角 大家看到了什么,是爱吗?不,这不是爱,不是爱,是满满的‘愁绪’?😂...
    一念之见阅读 2,113评论 0 2
  • 这篇文章紧跟上边autolayout的一些小技巧,如果你没有看过,不防先看下《你真的会用autolayout...
    槛内浊物阅读 10,156评论 7 46