同iOS以往每个迭代一样,iOS 9带来了很多新特性。UIKit框架每个版本都在改变,而在iOS 9比较特别的是UIStackView,它将从根本上改变开发者在iOS上创建用户界面的方式。本文将带你学习怎样使用UIStackView创建用户界面。

本文假定你已经熟悉Auto Layout基础。不熟悉的可以先看看Auto Layout教程。要理解Stack View为何如此有用及它是如何起作用的,需要首先对Auto Layout有深入了解。

1. 实例预览

我们将使用UIStackView模拟一个app评分提示。用户可以增加星星或者移除星星来打分。完成后看起来是这样。

先从GitHub下载样例工程并打开。在Main.Storyboard里有两个Stack View

我们将使用这两个Stack View来布局界面。开始编码前,让我们先看一下Stack View是如何工作的。

2. UIStackView 概述

Stack View的核心便是方便垂直或水平排布多个subview,如果你做过Android开发,那它和LinearLayout 控件非常相似。

Stack View最有用的就是它会自动为每个subview创建和添加Auto Layout constraints。当然你可以控制subview的大小和位置。可以通过选项配置subview的大小、排布以及彼此间的间距。

布局内容

打开Main.Storyboard,选择其中一个Stack View可以查看其选项,并选中一个Stack View。在 Attributes Inspector中,注意Stack View下面列出的选择。

Axis表示Stack View的subview是水平排布还是垂直排布。Alignment控制subview对齐方式。Distribution定义subview的分布方式。Spacing 为subview间的最小间距。

把术语简化一下,你可这样理解:Alignment 用于控制X 和 Y值,而Distribution 用于控制高度和宽度。另两个值都会影响对齐。如果选中Baseline Relative将根据subview的基线调整垂直间距。如果选中Layout Margins Relative 将相对于标准边界空白来调整subview位置。

另一个需要记住的是,Stack View会被当成Container View。所以它是一个不会被渲染的UIView子类。它不像其他UIView子类一样,会被渲染到屏幕上。这也意味着设置其backgroundColor属性或重载drawRect:方法都不会产生任何效果。

subView和arrangedSubView

开始使用Stack View前,我们先看一下它的属性subViews和arrangedSubvies属性的不同。如果你想添加一个subview给Stack View管理,你应该调用addArrangedSubview:或insertArrangedSubview:atIndex: arrangedSubviews数组是subviews属性的子集。

要移除Stack View管理的subview,需要调用removeArrangedSubview:和removeFromSuperview。移除arrangedSubview只是确保Stack View不再管理其约束,而非从视图层次结构中删除,理解这一点非常重要。

现在我们对Stack View有一定了解,开始使用它。

3. 配置垂直布局的Stack View

打开Main.Storyboard选择上面的Stack View。对Attributes Inspector作如下改变:

  • Alignment 设为 Center

  • Distribution 设为 Equal Spacing

  • Spacing 设为 30

这告诉Stack View为subview添加约束,使其垂直居中并沿Stack View的轴线对称,然后为subview设置边距30。

如果subview大小和Stack View内容区不相符,将根据compression resistance priorities对subview进行拉伸或压缩。在运行时给Stack View添加subview也同样会如此。

布局有任何歧义Stack View都会根据subview在arrangedSubviews中index一步步回退去调整subview的大小,直至其刚好适应Stack View的大小。

4. 给Stack View添加垂直布局的Subview

添加一个label,一个image view和一个button到上面的Stack View里。label在最上面,image view在中间,button在下面。添加完成后看起来是这样:

接下来,我们要在Attributes Inspector里修改一下刚才添加的subview的属性。把label的文本秘诀成“How do you likeour app?”, Text Alignment选择Center 。image view的Image 输入“logo”, Content Mode选Aspect Fit。最后把button的Text 设置成“Add Star!”。

运行app。能看到我们只做了很少工作,但已经添加了三个能响应方向、size class等改变的subview。事实上你并不需手动添加任何约束。

当app运行时,点击Xcode窗口底部Debug View Hierarchy按钮可以进行实时视图调试

选择先前添加的任意一个subview。查看size inspector,我们注意到Stack View已经自动为其添加了约束。下图显示的是为button添加的约束

5. 添加五角星

按钮事件还没和app界面关联,我们先关联起来。停止运行app,打开storyboard。创建一个名为addStar的IBAction 关联到按钮的Touch Up Inside事件。

addStar(_:)方法实现:

1
2
3
4
5
6
7
@IBAction func addStar(sender: AnyObject) {
    let starImgVw:UIImageView = UIImageView(image: UIImage(named: "star"))
    self.horizontalStackView.addArrangedSubview(starImgVw)
    UIView.animateWithDuration(0.25, animations: {
        self.horizontalStackView.layoutIfNeeded()
    })
}

给水平布局的Stack View里的星星image添加动画。记住,由于Stack View自动为我们管理Auto Layout constraints,我们只能调用layoutIfNeeded来实现动画。

编译运行app,点击add star按钮。能看到最后结果却不尽人意。

选择下面的Stack View,查看Attributes Inspector会看到问题所在。由于Alignment 和Distribution 都设置成了Fill,Stack View 拉伸了星星以适应其大小。

这在添加更多的星星的时候会引起更多问题。我们希望星星居中显示,而不是被拉伸来适应Stack View的宽度。

修改Alignment 的值为Center ,修改Distribution 的值为Fill Equally。最后在addStar(_:)方法中设置image view的内容。

1
2
3
4
5
6
7
8
@IBAction func addStar(sender: AnyObject) {
    let starImgVw:UIImageView = UIImageView(image: UIImage(named: "star"))
    starImgVw.contentMode = .ScaleAspectFit
    self.horizontalStackView.addArrangedSubview(starImgVw)
    UIView.animateWithDuration(0.25, animations: {
        self.horizontalStackView.layoutIfNeeded()
    })
}

运行app,点几次添加按钮,我们发现所有星星居中了。

6. Stack View嵌套

不能删除星星,我们的app评分什么用处不大。打开storyboard,添加一个水平布局的Stack View到上面的Stack View里。把它放置在logo之下,按钮之上。

把“Add Star!”按钮拖到新添加的Stack View里,再添加一个按钮到新的Stack View里。改变按钮的title为“Remove Star”,文本颜色设为red。预览如下:

在Attributes Inspector中编辑新Stack View的属性,改变如下:

  • Alignment 设为 Center

  • Distribution 设为 Equal Spacing

  • Spacing 设为 10

7. 删除五角星

为“Remove Star”按钮创建名为removeStar,事件类型为Touch Up Inside的IBAction响应方法。

removeAction(_:)实现:

1
2
3
4
5
6
7
8
9
10
11
@IBAction func removeStar(sender: AnyObject) {
    let star:UIView? = self.horizontalStackView.arrangedSubviews.last
    if let aStar = star
    {
        self.horizontalStackView.removeArrangedSubview(aStar)
        aStar.removeFromSuperview()
        UIView.animateWithDuration(0.25, animations: {
            self.horizontalStackView.layoutIfNeeded()
        })
    }
}

运行app,现在既可增加,也可删除了。改变模拟器方向或者旋转设备看看app会怎样调整其界面。我们并未添加一行约束就构建好了app的用户界面。

需要注意的是:removeStar(_:)里调用removeFromSuperview是把subview从视图层级中移除。再次调用removeArrangedSubview(_:)只是告诉Stack View不再需要管理subview的约束。而subview会一直保持在视图层级结构中直到调用removeFromSuperview把它移除。

结论

UIStackView类大大简化了用户界面开发。这是好事,特别是随着硬件的改变。使用UIStackView,减少了开发者为简单场景设置枯燥的约束,把繁杂的工作交给了UIKit。

如果对文中的任何知识点感兴趣,可以从 GitHub下载完整工程。

转载于:https://www.cnblogs.com/crash-wu/p/4846904.html

iOS 9: UIStackView入门相关推荐

  1. (0060)iOS开发之iOS 9: UIStackView入门

    iOS 9: UIStackView入门 UIStackView 同iOS以往每个迭代一样,iOS 9带来了很多新特性.UIKit框架每个版本都在改变,而在iOS 9比较特别的是UIStackView ...

  2. iOS 开发怎么入门?

    2017.5.22更新. 这次答案的更新主要想把此答案 ------------- 原文 ------------- 反对以上所有答案. 我反对理由如下:不管是斯坦福大学的CS193p公开课.苹果官方 ...

  3. 关东升的iOS实战系列图书 《iOS实战:入门与提高卷(Swift版)》已经上市

                承蒙广大读者的厚爱我的 <iOS实战:入门与提高卷(Swift版)>京东上市了,欢迎广大读者提出宝贵意见.http://item.jd.com/11766718 ...

  4. iOS 6 Passbook 入门 1/2

    步骤:(不完整) 1,生成pass.json的校验和: openssl sha1 pass.json 2,将生成的校验值置于manifest.json的pass.json的key-value下. 2, ...

  5. ios逆向傻瓜入门教程(一)

    1.准备工作: (1)一台越狱手机,并装有以下软件:cycript,openssh (2)下载工具库,内容列表: (3)在越狱手机上,从appstore上,下载WeChat(微信). 2.ssh到手机 ...

  6. 【转】iOS 开发怎么入门?

    原文网址:http://www.zhihu.com/question/20264108 iOS 开发怎么入门? 请问有设计模式.内存管理方面的资料吗?最好有除了官方文档之外的其它内容, 10 条评论 ...

  7. IOS 初级开发入门教程(四)基础控件使用小练习

    前言 看完前面3章的内容,基本对IOS开发有一些认识了,这章我们开始动手去实践做点小练习,学习如何创建并设置标签和按钮(Label & Button)的相关属性,以及通过一个交互式的案例演示动 ...

  8. 【图灵】iOS技能书单——入门+进阶+精通

    小编最近在研究一份不错的技能图谱(https://github.com/TeamStuQ/skill-map),遵照图谱精神,小编先做了个iOS技能书单,分享给大家. 老样子,点击书名查看完整目录和试 ...

  9. iOS开发ARC入门和使用

    本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论.请不要将本文的部分或全部内容用于商用,谢谢合作. 欢迎转载本文,但是转载请注明本文出处:http:/ ...

最新文章

  1. 早上突然看明白 shader和材质球的关系
  2. 编程入门:准备学Python入门编程 为什么前辈一直劝我不行?
  3. RedHat6.5-Linux安装telnet服务
  4. Java自学笔记(13):【面向对象】方法覆盖,final关键字,对象转型
  5. Python--day7--面向对象编程进阶
  6. APP远程调试及网络自动化测试
  7. c++语言自定义操作符,C++语言复习笔记二
  8. 2.24. Spring boot with Apache Kafka
  9. 华为云开天aPaaS 上线,服务千万开发者,使能行业场景化创新
  10. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(1)
  11. 2015年C语言组混搭 C/C++
  12. sourceInsight4 破解笔记(完美破解)【转】
  13. @column注解_Java 注解及其在 Android 中的应用
  14. React 与 React-Native 使用同一个 meteor 后台
  15. 明略科技吴明辉:每一次新数据都会带来商业模式的迭代 | 会员专栏
  16. 自定义gerrit提交脚本
  17. [TOG2019]Deferred Neural Rendering:Image Synthesis using Neural Textures
  18. 0x00007ffff3d3ecd0 in _IO_vfprintf_internal (s=0x7ffff40b5620 <_IO_2_1_stdout_>
  19. python真假判断
  20. 操作Mongodb数据库及性能测试

热门文章

  1. 黑客把你家网线作“天线”,读取电磁信号就能偷走数据
  2. 12张PPT看懂中国虚拟数字人产业现状:应用不止于虚拟偶像,2030年市场达2700亿|量子位智库(附下载)...
  3. 抖音出现大量“三岁用户”,马化腾李彦宏都被还童
  4. 开源FPGA硬件模拟游戏机,原汁原味的复古游戏体验带你回童年
  5. 最快的PNG图像解码器!速度提升2.75倍,比老大哥“libpng”还安全
  6. 穿上这件全球首款「隐形衣」,做这条街最「无脸」的仔;阿里给钱给资源,求解AI安全难题...
  7. 李飞飞、邓中翰当选美国国家工程院院士
  8. redis 一主二从
  9. MySQL中interactive_timeout和wait_timeout的区别
  10. java-集合排序,队列,散列表map以及如何遍历