iOS9 UIStackView 简介

作者:Umberto Raimondi,原文链接,原文日期:2015-12-08
译者:CoderAFI;校对:Channe;定稿:shanks

示例程序采用 Swift2.0 编写,需要用 Xcode7 进行编译,可以访问 Github 或者 zipped 下载本文源代码

iOS9 新加入了一个非常易用的布局控件 UIStackView,它可以将一组 UIView 视图进行垂直或水平方向的排列,用来替换手工使用 Auto Layout 对视图进行布局。

每个 UIStackView 控件都可以在垂直和水平方向上排列展示一组 subviews,并可以根据当前屏幕大小和方向的变化动态调整它的内容,感觉起来就像是一个隐形的容器。实际上 subviews 的位置是根据设置的对齐、间距和大小属性来决定的。

内部的原理是 UIStackView 类帮你管理了 Auto Layout 约束。想象一下 UIStackView 其实就是一个基于 Auto Layout 的抽象层从而使布局属性的创建简单化。你可以在一个主 UIStackView 中嵌套 UIStackView 从而让视图精确放置到相应的位置。

如果你做过 Android 开发,你会发现 UIStackView 概念跟 Android 中最常用的布局控件 LinearLayout 非常相似,这些布局的想法其实都是从早期的 Java Swing 开发中借鉴过来并加以完善的。

基础

UIStackView 既可以用代码编写也可以在 Interface Builder 中设计。

在 Interface Builder 中你可以从 Object Library 控件选择工具集里找到垂直或者水平对齐的 UIStackView 并添加到相应位置,然后就可以在 UIStackView 上添加新的视图了。

UIStackView 同样也可以对现有的一些视图进行包装,只需要选择他们并点击 Interface Builder 底部工具栏新加的Stack iconStack icon图标即可。

非常简单,但是我们的教程将用代码的方式实现一个简单的嵌套布局。

在这个简单的示例程序中,我们将会在状态栏下放置一个 UIStackView,里面包含四个控件:两个 UILabel,一个水平方向的 UIStackView 和 一个 UIButton。水平方向的 UIStackView 中包含了三个带有默认图标的按钮。

下面让我们创建一个 Single View Application,记住要将 Deployment Target 设置成 9.0+。

打开 ViewController 类并用下面的代码替换 viewDidLoad 方法:

var stackView:UIStackView!
var nestedStackView = UIStackView()

override func viewDidLoad() {
super.viewDidLoad()

stackView.translatesAutoresizingMaskIntoConstraints=false
self.view.addSubview(stackView)
// Main UIStackView contraints, nearly fills its parent view
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-30-[stackView]-30-|",options: NSLayoutFormatOptions.AlignAllLeading,metrics: nil, views: ["stackView":stackView]))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[stackView]-10-|",options: NSLayoutFormatOptions.AlignAllLeading,metrics: nil, views: ["stackView":stackView]))

stackView.axis = .Vertical
stackView.alignment = .Fill
stackView.spacing = 25
stackView.distribution = .FillEqually

var lbl = UILabel()
lbl.text ="Label 1"
lbl.backgroundColor = UIColor.redColor()
stackView.addArrangedSubview(lbl)

lbl = UILabel()
lbl.text = "Label 2"
lbl.backgroundColor = UIColor.greenColor()
stackView.addArrangedSubview(lbl)

nestedStackView.axis = .Horizontal
nestedStackView.alignment = .Fill
nestedStackView.spacing = 25
nestedStackView.distribution = .FillEqually
nestedStackView.addArrangedSubview(UIButton(type: .InfoDark))
nestedStackView.addArrangedSubview(UIButton(type: .InfoLight))
nestedStackView.addArrangedSubview(UIButton(type: .ContactAdd))
stackView.addArrangedSubview(nestedStackView)

let btn = UIButton(type: .System)
btn.setTitle("Press Me", forState: .Normal)
stackView.addArrangedSubview(btn)
}

为了指定主 UIStackView 是垂直方向布局的我们把 axis 属性设置成 .Vertical,前三个控件将会等间距排列,剩下的UIButton会填充剩余的可用空间。在嵌套 UIStackView 中的三个默认按钮也是用同样的方式来排列。alignmentdistributionspacing 三个属性会在下面单独讲解,这里我们先忽略它们。

有时候你可能需要将部分视图隐藏起来或者显示出来,这对于 UIStackView 来说实现起来是非常容易的,你只需要设置相应视图的 hidden 属性就可以。

为了方便测试,我们给 UIButton 添加一个 pressedMe 的点击事件响应方法:

    ...
btn.setTitle("Press Me", forState: .Normal)
btn.addTarget(self, action: "pressedMe:", forControlEvents: UIControlEvents.TouchUpInside)
stackView.addArrangedSubview(btn)

}

func pressedMe(sender: UIButton!){
UIView.animateWithDuration(0.5) {
self.nestedStackView.hidden = !self.nestedStackView.hidden
}
}

当点击这个按钮时,主 UISTackView 和 内部的 UISTackView 将会根据在 viewDidLoad 中设置的属性重新布局内部的子视图并带有短暂的显示或者隐藏动画效果。

如果需要,subviews 也可以完全从 UIStackView 中移除然后剩下的子视图也会根据各自的属性重新布局。

func pressedMe(sender: UIButton!){
stackView.removeArrangedSubview(nestedStackView)
nestedStackView.removeFromSuperview()
}

这个移除的操作需要两步,第一步是调用 removeArrangedSubview 方法用来从 UIStackView 删除视图并且重新布局剩余的 subviews 但是实际上并没有从父视图上删除。第二部就是调用 removeFromSuperview 方法以保证该视图从父视图中完全的被删除。

UIStackView: Alignment, Distribution And Spacing 属性

下面让我们详细了解下 UIStackView 的布局属性:

StackPropertyStackProperty

Axis 轴

定义子视图的布局方向,包含 Vertical(垂直) 和 Horizontal(水平)两个枚举值。

Alignment 对齐

alignment 属性指定了子视图在布局方向上的对齐方式,如果值是 Fill 则会调整子视图以适应空间变化,其他的值不会改变视图的大小。有效的值包含:Fill、 Leading、 Top、 FirstBaseline、 Center、 Trailing、 Bottom、 LastBaseline。

Distribution 分布

Distribution 属性定义了 subviews 的分布方式,可以赋值的5个枚举值可以分为两组: Fill 组 和 Spacing 组。

Fill 组用来调整 subviews 的大小,同时结合 spacing 属性来确定 subviews 之间的间距。

  • Fill: subviews 将会根据自己内容的内容阻力(content resistance)或者内容吸附优先级(hugging priority)进行动态拉伸,如果没有设置该值,subviews 中的一个子视图将会用来填充剩余可用空间。

  • FillEqually: 忽略其他的约束,subviews 将会在设置的布局方向上等宽或等高排列。

  • FillProportionally: subviews 将会根据自己的原始大小做适当的布局调整。

Spacing 组指定了 subviews 在布局方向上的间距填充方式,当 subviews 不满足布局条件或有不明确的的 Auto Layout 设置时,该类型的值就会结合相应的压缩阻力(compression resistance) 来改变 subviews 的大小。

  • EqualSpacing: subviews 等间距排列

  • EqualCentering: 在布局方向上居中的 subviews 等间距排列

Spacing 间距

spacing 属性根据当前 distribution 属性的值有不同方向的解释。

如果 UIStackView 的 distribution 属性设置的是 EqualSpacing、 EqualCentering,spacing 属性指的就是 subviews 之间的最小间距。相反如果设置的是 FillProportionally 属性,那么 spacing 的值就是严格的间距值。

iOS7+ 兼容

官方的 UIStackView 只在 iOS9 以上系统可以使用,但是其他的开源组织在低版本的系统上也实现了相应的功能:

内容概要:《2024年中国城市低空经济发展指数报告》由36氪研究院发布,指出低空经济作为新质生产力的代表,已成为中国经济新的增长点。报告从发展环境、资金投入、创新能力、基础支撑和发展成效五个维度构建了综合指数评价体系,评估了全国重点城市的低空经济发展状况。北京和深圳在总指数中名列前茅,分别以91.26和84.53的得分领先,展现出强大的资金投入、创新能力和基础支撑。低空经济主要涉及无人机、eVTOL(电动垂直起降飞行器)和直升机等产品,广泛应用于农业、物流、交通、应急救援等领域。政策支持、市场需求和技术进步共同推动了低空经济的快速发展,预计到2026年市场规模将突破万亿元。 适用人群:对低空经济发展感兴趣的政策制定者、投资者、企业和研究人员。 使用场景及目标:①了解低空经济的定义、分类和发展驱动力;②掌握低空经济的主要应用场景和市场规模预测;③评估各城市在低空经济发展中的表现和潜力;④为政策制定、投资决策和企业发展提供参考依据。 其他说明:报告强调了政策监管、产业生态建设和区域融合错位的重要性,提出了加强法律法规建设、人才储备和基础设施建设等建议。低空经济正加速向网络化、智能化、规模化和集聚化方向发展,各地应找准自身比较优势,实现差异化发展。
数据集一个高质量的医学图像数据集,专门用于脑肿瘤的检测和分类研究以下是关于这个数据集的详细介绍:该数据集包含5249张脑部MRI图像,分为训练集和验证集。每张图像都标注了边界框(Bounding Boxes),并按照脑肿瘤的类型分为四个类别:胶质瘤(Glioma)、脑膜瘤(Meningioma)、无肿瘤(No Tumor)和垂体瘤(Pituitary)。这些图像涵盖了不同的MRI扫描角度,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构,为模型训练提供了丰富多样的数据基础。高质量标注:边界框是通过LabelImg工具手动标注的,标注过程严谨,确保了标注的准确性和可靠性。多角度覆盖:图像从不同的MRI扫描角度拍摄,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构。数据清洗与筛选:数据集在创建过程中经过了彻底的清洗,去除了噪声、错误标注和质量不佳的图像,保证了数据的高质量。该数据集非常适合用于训练和验证深度学习模型,以实现脑肿瘤的检测和分类。它为开发医学图像处理中的计算机视觉应用提供了坚实的基础,能够帮助研究人员和开发人员构建更准确、更可靠的脑肿瘤诊断系统。这个数据集为脑肿瘤检测和分类的研究提供了宝贵的资源,能够帮助研究人员开发出更准确、更高效的诊断工具,从而为脑肿瘤患者的早期诊断和治疗规划提供支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值