在iOS9中,苹果引进了UIStackView,UIStackView可以方便的在你的应用中进行水平或者竖直方向进行试图的布局工作。而UIStackView会自动的管理它里面的子试图,并且让他们自动布局,达到自适应UI的分布效果。
UIStackView提供了一个高效的接口用于平铺一行或一列的视图组合。对于嵌入到StackView的视图,你不用再添加自动布局的约束 了。Stack View管理这些子视图的布局,并帮你自动布局约束。也就是说,这些子视图能够适应不同的屏幕尺寸。此外,你可以嵌入一个stack View到另一个stack view中来创建更为复杂的用户界面。不要误解我的意思,这并不意味着你就不需要处理自动布局了。你仍旧要定义一些布局约束来约束stack view。它只是帮你节约了为每个UI元素创建约束的时间,同时它更容易的从布局中添加/删除一个视图。
Xcode7提供两种方式使用UIStackView。
1. 从对象库中拖一个Stack View(水平的/竖直的)放到storyboard的正确位置上。然后你可以拖一些label,button,imageView等视图放到stack view中。
2. 自动布局栏中使用Stack选项。对于这个方式,你可以简单的选择两个或更多的视图,之后点击Stack选项(下图中红色标记的地方),IB将会把这些 视图嵌入到一个stackview中,并自动的调整。
一旦你添加了stack view,你可以改变一些stack view的属性来改变它的外观。
1. Axis选项决定视图是垂直布置还是水平布置。
2. Alignment选项控制这些视图的对齐方式。比如你如果设置成Leading,stack view管理的视图排列按Leading对齐。
3. Distribution属性决定了其管理的视图的大小和位置。默认设置为Fill。这是stack view尽量让它的所有子视图在一个合理的距离。
4. Spacing属性让你设置视图之间的间距。
在介绍完毕UIStackView的基本信息后,我们用一个Demo解释它的基本使用。你可以在GitHub中下载Demo的源代码。在分析Demo之前,我们先看看最终的运行效果:
界面中,有4个朋友的头像及两个分段控件。这个UI设计使用了自动布局并且适应任何的屏幕尺寸。令人惊讶的是:整个界面的UI设计,自动布局的约束只要作用与顶层的UIStackView即可。即只要设置顶层的UIStackView的约束即可,而其内部的相关约束,只需要设置顶层的UIStackView的属性或者嵌套UIStackView中的顶层的UIStackView的属性即可。下图中就是UI布局结构图:
然后,我们只需要设置 "Main Stack View"的约束:
UIStackView有垂直和水平两个方向的布局模式 (所以拖拽进去的子视图呈现形式如下):
现在我们来分析具体的布局:
1. "Person Stack View" 包含四张图片,你需要做的仅仅是将四张图片拖拽到"Person Stack View" 中,Demo中所使用的图片在尺寸上面有轻微的差别。并且我们不希望图片出现变形现象,所以应该设置所有图片的内容模式为"Aspect Fit"。这就意味着不管图片进行怎样的拉伸操作,图片将保持相同的宽高比。
2. "Stack View" 与 "Person Stack View" 是平级的, 它用来包装 下方的两个分段控件的区域。当 "Stack View" 与 "Person Stack View" 拖拽到"Main Stack View" 上面之后,我们就可以设置"Main Stack View" 的相关属性,来调节它内部内容的分布。
Axis设置为"Vertical": 就是 "Main Stack View" 内部的内容竖直分布; Spacing设置为 8; 就是其内部的内容间距为 8。
3. "Alignment Stack View" 和 "Distribution Stack View" 就是用来存放底部的分段控件及其说明文字的。很显然,分段控件和其前面的说明文字是水平分布的,所以我们设置"Alignment Stack View" 和 "Distribution Stack View" 的 Axis设置为"Horizontal"。
在布局完成之后,我们添加分段控件的相关事件,进行连线工作,并且添加事件代码,具体代码如下:
@interface ViewController () @property (weak, nonatomic) IBOutlet UIStackView *personStackView; - (IBAction)changeDistribution:(UISegmentedControl *)sender; - (IBAction)changeAlignment:(UISegmentedControl *)sender; @end @implementation ViewController - (IBAction)changeDistribution:(UISegmentedControl *)sender { NSInteger index = sender.selectedSegmentIndex; [UIView animateWithDuration:0.5 animations:^{ switch (index) { case 0: self.personStackView.distribution = UIStackViewDistributionFill; break; case 1: self.personStackView.distribution = UIStackViewDistributionFillEqually; break; case 2: self.personStackView.distribution = UIStackViewDistributionFillProportionally; break; case 3: self.personStackView.distribution = UIStackViewDistributionEqualSpacing; break; case 4: self.personStackView.distribution = UIStackViewDistributionEqualCentering; break; default: break; } }]; } - (IBAction)changeAlignment:(UISegmentedControl *)sender { NSInteger index = sender.selectedSegmentIndex; [UIView animateWithDuration:0.5 animations:^{ switch (index) { case 0: self.personStackView.alignment = UIStackViewAlignmentFill; break; case 1: self.personStackView.alignment = UIStackViewAlignmentTop; break; case 2: self.personStackView.alignment = UIStackViewAlignmentCenter; break; case 3: self.personStackView.alignment = UIStackViewAlignmentBottom; break; default: break; } }]; } @end
参考文章:
http://www.open-open.com/lib/view/open1440081657817.html
http://www.csdn.net/article/2015-08-04/2825372/1