这是第二篇关于AutoLayout的文章。<EmbedIn>StackView来插入一个stackview,这和点击EmbedInStack没什么区别。1.创建一个demo这里,使用TabbedApplication模板创建一个demo,设置ProductName为StackView,选择文件位置,创建一个项目。让我们通过三个例子来学习StackView。2、示例1打开新建demo的Main.storyboard,在FirstScene中添加如下视图:第一行是UILabel和UISwitch,第二行是两个UIImageView。选择第一行的UILabel和UISwitch,然后单击EmbedInStack以插入StackView。打开AttributesInspector,设置StackView的属性如下:Axis:Horizo??ntal,自动创建的应该是Horizo??ntal,不用修改。Alignment:CenterDistribution:Fill,不需要修改。Spacing:16选择两个UIImageView,重复上面的步骤插入一个StackView,修改属性,属性同上。UIImageView中图片的ContentMode属性是AspectFit。选中刚刚添加的两个StackView,点击EmbedInStack,再次插入一个stackview。堆栈视图可以嵌入堆栈视图。InterfaceBuilder自动插入垂直堆栈视图。修改其属性如下:Axis:Vertical,不需要修改。Alignment:CenterDistribution:Fill,不需要修改。间距:16堆栈视图根据子视图的大小调整其大小。这里,子视图保持了固有的内容大小,所以只需要添加约束来指定stackview的位置,不需要约束stackview的大小。添加约束,指定堆栈视图水平居中,距离顶部20点。如果在添加过程中遇到问题,可以点击这里查看demo,或者查看之前的文章了解如何添加约束。添加后,视图层级如下:使用StackView时,一般只需要指定stackview的位置,stackview的大小会根据子视图的大小动态调整。堆栈视图中子视图的显示顺序由它们在arrangedSubviews数组中的顺序决定。在水平堆栈视图中,视图的显示方向与阅读方向一致,优先显示arrangedSubviews数组中索引号较小的视图。在垂直堆栈视图中,视图从上到下显示,索引较低的视图在顶部,索引较高的视图在底部。当从arrangedSubviews数组中添加、删除或隐藏视图时,StackView会自动调整布局。接下来,从UISwitch连接一个IBAction属性,并在单击UISwitch时调整imageStackView的轴。imageStackView是故事板中图像堆栈视图的IBOutlet属性。-(IBAction)axisChange:(UISwitch*)sender{[UIViewanimateWithDuration:0.25动画:^{[selfupdateConstraintsForAxis];}];}-(void)updateConstraintsForAxis{//在水平和垂直堆栈视图之间切换}else{self.imageStackView.axis=UILayoutConstraintAxisHorizo??ntal;}}使用animateWithDuration:animations:方法为视图的转换设置动画。3.示例2通过示例1,我们可以在运行时手动修改stackview轴,但更好的方法是StackView随设备自动旋转。例如,当设备从纵向旋转到横向时,堆栈视图轴属性会自动从UILayoutConstraintAxisVertical调整为UILayoutConstraintAxisHorizo??ntal。进入第二个场景,添加两个UIImageView,contentMode属性为AspectFit,图片分别为Heart和Star。可以从文末网址下载源码获取图片。选择两个UIImageViews以插入水平堆栈视图。堆栈视图与Leading、Trailing、Top和Bottom之间的距离分别为0、0、StandardValue和StandardValue。StackView的其他属性如下:Axis:Horizo??ntalAlignment:CenterDistribution:FillProportionallySpacing:0上面的Distribution有五个属性:Fill,FillEqually,FillProportionally,EqualSpacing,EqualCentering。这五个属性之间的区别:UIStackViewDistributionFill:StackViewadjuster视图调整大小以填充所有可用空间。当子视图的大小大于可用空间时,视图按照CompressionResistance优先级进行压缩;当子视图无法填充可用空间时,视图会根据ContentHugging优先级进行拉伸。如果优先级相同,则优先调整arrangedSubviews数组中索引较小的视图。UIStackViewDistributionFillEqually:将所有子视图调整为相同大小,占用所有可用空间。UIStackViewDistributionFillProportionally:它会保持每个子视图的固有大小,但是如果有可用空间或者视图需要压缩,它会按比例拉伸和压缩。例如,如果一个视图是100宽,另一个视图是200宽,StackView想要拉伸视图以填充可用空间,则第一个视图拉伸到150宽,第二个视图拉伸到300宽。UIStackViewDistributionEqualSpacing:不调整子视图的大小,通过移动子视图使子视图等间距。如果子视图大于可用空间,它将根据CompressionResistance优先级进行压缩。如果优先级相同,则优先调整arrangedSubviews数组中索引较小的视图。UIStackViewDistributionEqualCentering:使子视图的中心距离相等。如果视图大于可用空间,spacing属性将被压缩直到设置的最小值。如果此时仍然大于可用空间,则子视图将按照子视图的CompressionResistance优先级进行压缩。如果优先级相同,则优先调整arrangedSubviews数组中索引较小的视图。选择StackView,打开AttributesInspector,你会发现每个StackView属性前面都有一个+。单击这些+以自定义水平和垂直堆栈视图的属性。接下来,添加一个属性,当宽度紧凑且高度规则时,轴是垂直的。同理,当宽度紧凑,高度规则时,也可以添加一个spacing属性。一般不需要添加其他属性。现在运行应用程序,当屏幕是纵向时,stackview的轴是垂直的;当屏幕是横向时,堆栈视图的轴是水平的。4.Example3StackView的主要优点之一是它自动为其每个子视图创建自动布局约束,并且还可以设置这些子视图的大小和位置。在新建的demo中添加一个ViewController,连接到tabcontroller,设置BarItem的title为Third。打开ThirdScene,从上到下依次添加UILabel、UIImageView、UIButton,插入到一个垂直的stackview中。stackview的属性设置如下:Axis:VerticalAlignment:CenterDistribution:EqualSpacingSpacing:0UIImageView的contentMode为AspectFit,并在上面的StackView中添加约束,与Leading、Trailing、Top的距离为分别为0、0和20。在上图中AddStar下添加一个水平的stackview,设置属性如下:Axis:Horizo??ntalAlignment:CenterDistribution:FillEquallySpacing:10完成后为其添加约束,以及Leading、Trailing、Top、Bottom的距离分别是0、0、StandardValue、20、高度120。UIStackView虽然继承自UIView,但只是管理子视图的位置和大小,不提供用户界面,即部分属性不适用到UIStackView,比如backgroundColor,并且不能覆盖drawRect:方法。stackview中有subviews和arrangedSubviews两个属性,遵守以下规则。当StackView将视图添加到arrangedSubviews数组时,它还会将该视图添加为子视图。从StackView中移除视图也会将其从arrangedSubviews数组中移除。从arrangedSubviews数组中删除一个视图,该视图仍然存在于subviews数组中。StackView不管理移除视图的位置和大小,但它会存在于视图层次结构中。因此,通过调用addArrangedSubview:或insertArrangedSubview:atIndex:方法向arrangedSubviews数组中添加一个元素,该元素将同时添加到subviews数组中。通过removeFromSuperView方法删除的视图将同步从arrangedSubviews数组中删除。通过removeArrangedSubview:删除的视图将仍然存在于subviews数组中。从UIButton连接一个名为addStar的IBAction单击事件。单击时,在horizo??ntalStackView底部添加一个五角星。-(IBAction)addStar:(UIButton*)sender{UIImageView*filledStarView=[[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"filledStar"]];//添加视图到堆栈视图[self.horizo??ntalStackViewaddArrangedSubview:filledStarView];filledStarView.contentMode=UIViewContentModeScaleAspectFit;[UIViewanimateWithDuration:0.25动画:^{[self.horizo??ntalStackViewlayoutIfNeeded];}];}现在添加去除五角星的功能。从添加星标下的对象库中拖放一个UIButton。选择UIButton和AddStar,然后单击EmbedInStack按钮以插入堆栈视图。修改新插入的stackview的属性如下:Axis:Horizo??ntalAlignment:CenterDistribution:EqualSpacingSpacing:10刚添加的UIButton标题为RemoveStar,文字颜色为红色。为刚刚添加的UIButton创建一个名为removeStar的IBAction点击事件,并实现remove方法。-(IBAction)removeStar:(UIButton*)sender{UIView*filledView=self.horizo??ntalStackView.arrangedSubviews.lastObject;//如果视图存在,移除视图if(filledView){[filledViewremoveFromSuperview];//会自动从arrangedSubviews中移出Exceptfor[UIViewanimateWithDuration:0.25animations:^{[self.horizo??ntalStackViewlayoutIfNeeded];}];}}运行应用程序,您现在可以添加和删除五角星,视图将随着设备旋转自动调整布局。小结通过本文可以看到,UIStackView大大降低了用户界面开发的难度,简化了很多工作,只需要添加少量的约束就可以实现自动布局。布局时,优先使用StackView布局界面。Demo名称:StackView源码地址:https://github.com/pro648/Bas...参考:StacksiOS9:GettingStartedwithUIStackViewUIStackView分布类型有哪些?欢迎更多指正:https://github.com/pro648/tips本文地址:https://github.com/pro648/tip...