iOS开发——UI篇Swift篇&iOS 9 UIStackView

iOS 9 UIStackView

一、继承关系、遵守协议、隶属框架及可用平台

UIStackView 类提供了一个高效的接口用于平铺一行或一列的视图组合。Stack视图使你依靠自动布局的能力,创建用户接口使得可以动态的调整设备朝向、屏幕尺寸及任何 可用范围内的变化。Stack视图管理着所有在它的 arrangedSubviews 属性中的视图的布局。这些视图根据它们在 arrangedSubviews 数组中的顺序沿着 Stack 视图的轴向排列。精确的布局变量根据 Stack 视图的 axis, distribution, alignment, spacing, 和其它属性共同决定。

使 用 stack 视图,打开一个你希望编辑的 Storyboard,从对象库中拖拽出一个 Horizontal Stack View 或者一个 Vertical Stack View,并放置到你希望的位置上。下一步,将控件或视图拖拽放置到 stack 中,如果需要你可以继续添加视图或者控件给指定的 stack。Interface Builder 将根据 stack 的内容自动调节尺寸。你也可以通过修改属性面板中 Stack视图的属性调整 stack 内容的外观。

注意:你需要负责指定 stack 视图的位置和尺寸(可选的)。然后 stack 视图将管理其内容的布局和尺寸。

二、Stack 视图与自动布局

Stack 视图使用自动布局来定位和控制其管理的视图的尺寸。stack 视图沿着它的轴向拼凑第一个和最后一个被管理视图,使其边界平齐。对于一个水平 stack 视图,这意味着第一个被管理视图的左边界是与 stack 的左边界平齐的,并且最后一个被管理视图右边界与 stack的右边界平齐。对于垂直 stack,上边界和下边界是各自平齐的。如果你设置了 stack 视图的 layoutMarginsRelativeArrangement 属性为 YES,stack 视图将使用相关的边距与其内容对齐,而不是边界。

对 于除去 UIStackViewDistributionFillEqually 分布以外的分布方式,stack 视图使用被管理视图的 intrinsicContentSize 属性来计算沿着 stack 轴向的视图尺寸。UIStackViewDistributionFillEqually 分布将调节所有被管理视图的在 stack 轴向上拥有相同尺寸,以填充 stack 视图。如果可能,stack 视图将拉伸所有被管理视图,来匹配其在 stack 轴向上最长的原有尺寸(译注:保证长宽比的情况下根据 stack 轴向长度拉伸视图)。

对于除去 UIStackViewAlignmentFill 对齐方式以外的对齐方式,stack 视图使用其管理的视图的 intrinsicContentSize 属性来计算视图垂直于 stack 轴向的尺寸。 UIStackViewAlignmentFill 重新调节了所有其管理的视图,使这些视图填充 stack 视图垂直于其轴向空间。如果可能,stack 视图将拉伸其所有管理的视图来匹配其垂直于 stack 轴向的最大固有尺寸。

三、定位和调整 Stack 视图尺寸

当 Stack 视图允许你布局其内容而不直接使用自动布局,你将仍然需要使用自动布局来定位 stack 视图。通常情况下,这意味着需要拼凑至少两个边界相邻的stack来定义它的位置。没有额外约束的情况下,系统会为 stack 视图计算一个尺寸来适应其内容:

  • 沿着 stack 视图轴向,其适应尺寸等于其管理的视图尺寸与间距的和;
  • 垂直于 stack 视图轴向,其适应尺寸等于其管理的视图中最大的视图的尺寸;
  • 如果 stack 视图的 layoutMarginsRelativeArrangement 属性设置为 YES,stack 视图的适应尺寸会包括边距空间。

你 可以提供额外的约束来具体说明 stack 视图的高度、宽度或者两者兼有。在这些情况下,stack 视图调整了其管理的视图的布局和尺寸来填充指定区域。精确的布局变量根据 stack 视图的属性获得。可以通过查看 UIStackViewDistribution 和 UIStackViewAlignment 枚举,以获得一个完整的 stack 视图在其内容空间多余或空间不足情况下的处理描述。

你也可以根据 stack 视图的第一条或最后一条基线定位它,而不是使用顶部、底部或者中心的Y值。类似于 stack 视图的适应尺寸,这些基线都是基于 stack 视图的内容计算得到的。

  • 一 个水平的 stack 视图调用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法时返回它最高的视图。如果最高的视图也是一个 stack 视图,那么其返回的将是在嵌套的 stack 视图上调用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法的结果。
  • 一 个垂直的 stack 视图当调用 viewForFirstBaselineLayout 方法时返回的是其管理的第一个视图,当调用 viewForLastBaselineLayout 方法时返回的是其管理的最后一个视图。如果这两个视图之一也是 stack 视图,那么其返回的将是在嵌套的 stack 视图上对应调用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法的结果。

注意:基线对齐方式只作用于那些高度匹配其原本内容高度的视图。如果视图被拉伸或压缩过,那么基线将出现在错误的位置上。

四、通用 Stack 视图布局

这有一些通用方法用于 stack 视图。这个清单是要高亮一些有用的示例来显示 stack 视图的灵活性。目前这还不是一个完整的清单。

  • 只是定义位置。你 可以通过固定两个与其父视图相邻的边界来定义 stack 视图的位置。在这里,stack 视图的尺寸将根据其管理的视图在两个维度上自由扩展。当你想要 stack 视图的内容展现其原有内容尺寸,和你想要管理其他与 stack 视图有关联的用户接口元素时是特别有用的。

举个例子,在 Figure 1中,stack 视图的左边界和上边界都已经相对固定于其父视图。这些标签将根据带有8个点的两者之间的空间作为第一基线校准。这对于相对于其本身左对齐的 stack 视图内容是有效的。

Figure 1.定义位置

  • 定义沿着 stack 视图轴向的尺寸。这 里,你固定了沿着 stack 视图轴向相对于其父视图的两个边界,定义了 stack 视图沿着其轴向的尺寸。你将需要固定其他边界中的一个来定义 stack 视图的位置。stack 视图将沿着其轴向改变尺寸和位置来填充定义的空间;然而,未固定的边界将根据其管理的最大视图的尺寸自由移动。

举例如 Figure 2,stack 视图的左、上、右边界都已经相对于其父视图固定了。使用 UIStackViewDistributionFill 分布使得其内容重设尺寸来填充它的宽度,并且从文本框有比标签更低的内容紧凑优先级开始,它将在必要的时候被拉伸。

Figure 2.定义沿着 stack 视图轴向的尺寸

  • 定义垂直于 stack 视图轴向的尺寸。这 类似于上一个示例,但是你固定了垂直于 stack 视图轴向的两个边界和沿着轴向的一个边界。这使得 stack 视图在你增加或移除其管理的视图时将沿着其轴向扩展或回缩。除非你使用了 UIStackViewDistributionFillEqually 分布,被管理的视图将根据其原有尺寸调节尺寸。垂直于其轴向的视图将根据其 stack 视图的对其模式在其定义的范围内平铺。

举 例,Figure 3展示了一个包含了四个标签和一个按钮的垂直 stack 视图。这个 stack 视图使用了8个点的间隙和 UIStackViewAlignmentCenter 对齐方式。stack 视图的高度将根据 stack 内部的元素的增减而增大或回缩。

Figure 3.定义垂直于 stack 视图轴向的尺寸

  • 同时定义 stack 视图的位置和尺寸。这 里你固定了 stack 视图的所有四个边界。stack 视图将在提供的范围之内平铺其内容。举例,Figure 4展示了一个所有四个边界都相对于其父视图固定的垂直 stack 视图。通过使用 UIStackViewAlignmentCenter 对齐方式和 UIStackViewDistributionFill 分布方式,stack 视图确保其内容将水平和垂直居中填充屏幕。然而,获得想要的布局需要两个额外的步骤。默认情况下,stack视图会垂直拉伸标签而不是图片。要缩放图片控 件,就要降低其内容紧凑优先级到低于标签。额外的,为了保持图片缩放时的长宽比,你必须设置图片视图的模式为 Aspect Fit。增加一个图片视图与 stack 视图间宽度相等约束将有助于确保图片将被缩放来填充可用范围。

Figure 4.同时定义 stack 视图的位置和尺寸

五、管理 Stack 视图的展现

UIStackView 是 UIView 的非渲染型子类。它没有提供其自有的任何用户接口。相反的,它只管理被其管理的视图的位置和尺寸。因此,有些属性(如 backgroundColor)在 stack 视图上是无效的。类似的,你无法重写 layerClass,drawRect: 或 drawLayer:inContext: 方法。

这里有一系列的属性来定义 stack 视图如何平铺其内容。

  • axis(轴向) 属性决定了 stack 的朝向,只有垂直或水平;
  • distribution(分布) 属性决定了其管理的视图在沿着其轴向上的布局;
  • alignment(对齐) 属性决定了其管理的视图在垂直于其轴向上的布局;
  • spacing(空隙) 属性决定了其管理的视图间的最小间隙;
  • baselineRelativeArrangement 属性决定了其视图间的垂直间隙是否根据基线测量得到;
  • layoutMarginsRelativeArrangement 属性决定了 stack 视图平铺其管理的视图时是否要参照它的布局边距

通 常情况下,你会使用一个 stack 视图来布局小数量的视图。你可以通过在其他 stack 视图中嵌套多个 stack 视图的方式创建更加复杂的视图层次结构。举例,Figure 5展示了一个包含两个水平 stack 视图的垂直 stack 视图。每一个水平 stack 视图各包含一个标签和一个文本框。

Figure 5.Stack 视图的嵌套

你 也可以通过增加被管理的视图的额外约束来完美的调节一个被管理视图的展现。举例说明,你可以使用约束类设置视图的最小或最大的高度或宽度。或者你可以定义 一个长宽比。当平铺其内容时,stack 视图将使用这些约束。举例来说,在Figure 4中,当图片被缩放时,图片视图的一个长宽比约束被强行赋予了一个长宽比常数。

注意:当给一个 stack 视图内的视图增加约束时要特别注意避免传入冲突。作为惯例,如果一个视图的尺寸在一个指定的维度上默认回到其原本内容尺寸,那么你可以安全的在这个维度上增加约束。

六、维护其管理的视图与子视图之间的统一性

Stack 视图确保它的 arrangedSubviews 属性将一直是其 subviews 属性的子集合。明确的说,stack 视图强制实施了以下规定:

  • 无论何时 stack 视图增加了一个视图到它的 arrangedSubviews 数组,其也将把这个视图作为子视图增加,如果还未增加的话。
  • 无论何时一个子视图从 stack 视图中被移除,那么 stack 视图也将将其从 arrangedSubviews 数组中移除。
  • 从 arrangedSubviews 移除一个视图并不会将其作为子视图移除。stack 视图将不再管理该视图的尺寸和位置,但是该视图仍将是视图结构的一部分,并且当其可见的情况下仍会被渲染到屏幕上。

当 arrangedSubviews 数组一直包含着 subviews 数组的子集合,这些数组间的顺序仍然是独立的。

  • arrangedSubviews 数组的顺序定义了展现在 stack 中的视图的顺序。对于水平 stack 视图,这些视图将以阅读顺序平铺,即较小索引的视图在较大索引视图的左侧。对于垂直 stack 视图,这些视图是从上到下平铺的,及较小索引的视图在较大索引视图的上方。
  • subviews 数组中的顺序定义了子视图在Z轴上是顺序。如果视图重叠,有较小索引的子视图将出现在有较大索引的子视图后方。

七、动态改变 Stack 视图内容

当视图被加入、移出或插入 arrangedSubviews 数组时,或当一个被管理的子视图的 hidden 属性改变时,stack 视图都会自动更新它的布局。

OC代码如下:

1 // Appears to remove the first arranged view from the stack.
2 // The view is still inside the stack, it‘s just no longer visible, and no longer contributes to the layout.
3 UIView * firstView = self.stackView.arrangedSubviews[0];
4 firstView.hidden = YES;

Swift代码如下:

1 // Appears to remove the first arranged view from the stack.
2 // The view is still inside the stack, it‘s just no longer visible, and no longer contributes to the layout.
3 let firstView = stackView.arrangedSubviews[0]
4 firstView.hidden = true

stack 视图也会自动响应其任何属性的改变。举例,你可以更新 stack 视图的 axis 属性来动态改变的朝向。

OC代码如下:

1 // Toggle between a vertical and horizontal stack
2 if (self.stackView.axis == UILayoutConstraintAxisHorizontal) {
3 self.stackView.axis = UILayoutConstraintAxisVertical;
4 }else {
5 self.stackView.axis = UILayoutConstraintAxisHorizontal;
6 }

Swift代码如下:

1 // Toggle between a vertical and horizontal stack
2 if stackView.axis == .Horizontal {
3 stackView.axis = .Vertical
4 }else {
5 stackView.axis = .Horizontal
6 }

对于被管理的子视图的 hidden 属性的变化和 stack 视图属性的变化,你可以通过将这些改变内置到一个动画块代码的方式以动画方式展现。

OC代码如下:

1 // Animates removing the first item in the stack.
2 [UIView animateWithDuration:0.25 animations:^{
3 UIView * firstView = self.stackView.arrangedSubviews[0];
4 firstView.hidden = YES;
5 }];

Swift代码如下:

1 // Animates removing the first item in the stack.
2 UIView.animateWithDuration(0.25) { () -> Void in
3 let firstView = stackView.arrangedSubviews[0]
4 firstView.hidden = true}

最后,你可以直接在Interface Builder中给很多 stack 视图属性定义特定的 “尺寸类” 类型值。系统将在 stack 视图的尺寸类改变时动画展现这些改变。

八、常用的方法

创建 Stack 视图

1 - initWithArrangedSubviews: (New in iOS 9.0)

管理安排的子视图

1 - addArrangedSubview: (New in iOS 9.0)
2   arrangedSubviews Property (New in iOS 9.0)
3 - insertArrangedSubview:atIndex: (New in iOS 9.0)
4 - removeArrangedSubview: (New in iOS 9.0)

设置布局

1 alignment Property  (New in iOS 9.0)
2 axis Property  (New in iOS 9.0)
3 baselineRelativeArrangement Property  (New in iOS 9.0)
4 distribution Property  (New in iOS 9.0)
5 layoutMarginsRelativeArrangement Property  (New in iOS 9.0)
6 spacing Property  (New in iOS 9.0)

常量

1 UIStackViewDistribution
2 UIStackViewAlignment
时间: 2024-10-12 13:18:35

iOS开发——UI篇Swift篇&iOS 9 UIStackView的相关文章

iOS开发——UI高级Swift篇&swift简单总结tableView

swift简单总结tableView 今天来总结一个很简单的问题,真心说出来丢脸,但是由于本人在写swift项目的时候总是发现Xib不能加载,而且不止一次,所以就简单的总结一下! 一:简单的使用缓存池 1.设置StoryBoard中cell的ID 2.在控制器的Cell中就可以直接使用ID创建了 1 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UI

iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

Swift 2.0和Objective-C2.0混编之第三方框架的使用 swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引入了多种新功能,使得编程工作更加简便,灵活! 2015年6月9日苹果又一次给所有开发之者带来了一个惊喜,那就是今年年底swift讲开源,者队iOS开发着来说无疑是一个值得兴奋的消息,可是就在这短短的几个月里面swift吸引了越来

iOS开发——新特性Swift篇&Swift 2.0 异常处理

Swift 2.0 异常处理 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主要围绕这个方面进行讨论. 如何建造异常类型? 在 iOS 开发当中,我们会面对很多异常处理.在 Cocoa Touch 中我们使用 NSError 来进行异常处理.在新的 Swift 2.0 中,我们可以使用新的 ErrorType protocol. 在 Swift 中, enum 是最好的方法建立属于你自己的异常类型,你只要在你的 enum 中确

iOS开发——UI精选OC篇&UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍

UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道,单例在应用程序的整个生命周期中只有一个对象). App的启动过程 打开程序之后-> 1:Main函数 2:UIapplicationMain函数 3:初始化UIApplication(创建) 4:设置UIApplication代理和相应的代理属性 5:开启事件循环,监听系统事件 6监测info.p

iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver

IOS数据持久化的方式分为三种: 属性列表 (plist.NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等 归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上:程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象.本文主要介绍swift实现iOS数据归档. 归档Foundation框架对象 func archiveData(){ var path: AnyObject=NS

iOS开发——网络编程Swift篇&Alamofire详解

Alamofire详解 预览图 Swift Alamofire 简介 Alamofire是 Swift 语言的 HTTP 网络开发工具包,相当于Swift实现AFNetworking版本. 当然,AFNetworking非常稳定,在Mac OSX与iOS中也能像其他Objective-C代码一样用Swift编写.不过Alamofire更适合Swift语言风格习惯(Alamofire与AFNetworking可以共存一个项目中,互不影响). Alamofire 取名来源于Alamo Fire fl

iOS开发——学习总结swift篇&swift 2.0学习与总结一

swift 2.0学习与总结一 一:属性策略(OC中的叫法) strong: 在Swift中是默认的 weak: 通过weak关键词申明 weak var delegate: UITextFieldDelegate? readonly,readwrie 直接通过声明变量var,声明常量let的方式来指明 copy 通过@NSCopying指令声明. 值 得注意的是String,Array和Dictionary在Swift是以值类型(value type)而不是引用类型(reference typ

iOS开发——图形编程Swift篇&CAShapeLayer实现圆形图片加载动画

CAShapeLayer实现圆形图片加载动画 几个星期之前,Michael Villar在Motion试验中创建一个非常有趣的加载动画. 下面的GIF图片展示这个加载动画,它将一个圆形进度指示器和圆形渐现动画结合.这个组合的效果有趣,独一无二和有点迷人. 这个教程将会教你如何使用Swift和Core Animatoin来重新创建这个效果.让我们开始吧! 基础 首先下载这个教程的启动项目,然后编译和运行.过一会之后,你应该看到一个简单的image显示: 这 个启动项目已经预先在恰当的位置将view

iOS开发——网络编程Swift篇&(八)SwiftyJSON详解

SwiftyJSON详解 最近看了一些网络请求的例子,发现Swift在解析JSON数据时特别别扭,总是要写一大堆的downcast(as?)和可选(Optional),看?号都看花了.随后发现了这个库SwiftyJSON,问题迎刃而解,灰常优雅和Swifty! 简单介绍下这个库(内容译自SwiftyJSON的README): 为什么典型的在Swift中处理JSON的方法不好? Swift语言是一种严格的类型安全语言,它要求我们显示的设置类型,并帮助我们写出更少bug的代码.但是当处理JSON这种

iOS开发——项目实战Swift篇&swift 2.0项目开发总结二(开发常用)

swift 2.0项目开发总结二(开发常用) 一:相册中选择相片到App指定位置 随 着相机像素的提高,实际用户选择的图片都是很大的,有的高达5.6M,如果直接使用用户选着的图片,非常消耗内存,并且也用不到这么高像素的图片,可以当 用户选着好图片后,在UIImagePickerController对应的代理方法中,先将图片进行重新绘制为需要的大小,在设置给iconView 1 /// MARK: 摄像机和相册的操作和代理方法 2 extension MeViewController: UIIma