纯代码布局,也可以一样的简洁
theme: juejin highlight: xcode
“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第3篇文章,点击查看活动详情”
前言
在前两篇文章讲述了UIStackView布局思想,使用方法以及一些实用的案例,在案例中使用xib结合UIStackView,缺少一些对纯代码的补充,这篇文章,我们主要聊聊如何使用StackView来写纯代码布局。
即便说过很多StackView的好,但是还是很多人认为复杂的页面用不上,其实真正理解了StackView的布局思想,不管是结构层级简单的布局亦或者复杂的布局,也不管是使用Inferface Builder
来构建UI,还是使用纯代码,都能够游刃有余。
下面,我会使用swift演示使用纯代码是怎样布局的。如果有兴趣,点击下载Demo查看效果。下面所展示的代码只是截取的布局部分。
简单布局
简单布局,我归纳为,一行或者一列的元素组成的。通常有类页面如设置页、通讯录。如下布局中,一个hStack包含了image、label、button,组成了一个简单的布局。
结构如下:\ HStack: image + label + Button
swift
/// 懒加载
private lazy var vStack = VStack(spacing: 16)
Note: 这里的
VStack
实际上是对UIStackView的封装以及添加了便携式的初始化,并不是SwiftUI
中VStack
。
```swift /// 布局代码 addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
/// 这里是使用的扩展方法 iconView.sizeConstraint = CGSize(width: 40, height: 40) title.heightConstraint = 30 follow.sizeConstraint = CGSize(width: 60, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, title, hStack.spacer(), follow]) ```
Note:
sizeConstraint、heightConstraint、widthConstraint、addArrangedSubviewsMakeConstraint、spacer()
这些都是自己添加分类方法。
嵌套布局
嵌套布局,我归纳为,界面的元素多样化,需要使用两个以上StackView的布局(不同排列方向)。
结构如下:\ HStack:image + VStack + Button\ VStack:label + label
swift
/// 懒加载
private lazy var hStack = HStack(spacing: 8, alignment: .center, distribution: .fill)
private lazy var vStack = VStack(spacing: 4, alignment: .fill, distribution: .fill)
Note:
swift
可以写出比OC
更多的语法糖,这是语法的特性所在。从初始化方法上就可以看出。
```swift addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
iconView.sizeConstraint = CGSize(width: 50, height: 50) helpView.sizeConstraint = CGSize(width: 30, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, vStack, hStack.spacer(), helpView]) vStack.addArrangedSubviews([title, detail]) ```
动态更新布局
动态更新布局,我归纳为,界面的元素多样化,一些界面上的元素会有种状态,继而影响到其他的元素,最终会影响到整体的布局。
结构如下:\ HStack:image + VStack + Button\ VStack:HStack + label\ HStack:label + label
其实整体的布局,与上面的例子中仅仅只有细微的差别,这里想要体现的是,修改stackView的属性以及修改stackView中的排列视图的width、height或者hidden相关的属性,都会使stackView重新布局。
```swift private lazy var hStack = HStack(spacing: 8, alignment: .center, distribution: .fill) private lazy var vStack = VStack(spacing: 4, alignment: .fill, distribution: .fill) private lazy var titleHStack = HStack(spacing: 4, alignment: .center, distribution: .fill)
private var isFollow: Bool = false { didSet { self.follow.isHidden = isFollow self.followLabel.isHidden = !isFollow } } ```
```swift addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
iconView.sizeConstraint = CGSize(width: 50, height: 50) follow.sizeConstraint = CGSize(width: 60, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, vStack, hStack.spacer(), follow]) vStack.addArrangedSubviews([titleHStack, detail])
followLabel.sizeConstraint = CGSize(width: 50, height: 15) titleHStack.addArrangedSubviewsMakeConstraint([title, followLabel, titleHStack.spacer()]) ```
滚动布局
StackView有时候也可以使用配合ScrollView
一起使用,效果如同TableView,但是这个则需要使用好ScrollView的contentSize
,使用frame布局,则需要手动设置;使用自动布局,则需要ScrollView中的contentView来填充,最终ScrollView的contentSize取决于contentView。
有时候,写个简单的页面,真的不需要那么多代理,这不是更简单吗?
```swift view.addSubview(scrollView) scrollView.snp.makeConstraints { make in make.edges.equalTo(view.safeAreaLayoutGuide) }
scrollView.addSubview(vStack) vStack.snp.makeConstraints { make in make.edges.equalToSuperview(); make.width.equalToSuperview() } ```
结尾
文章使用了几个简单的实例,一点点的演变了不同的布局方式,在我们日常开发中,或许有那些简单极致的页面,或许也有那些花里胡哨的页面,不管如何,布局的思路都不会变,其实从实例中可以看出,布局代码所占篇幅并不多,在配合使用一些扩展类,其实使用StackView纯代码布局是不是比想象中要香很多呢。
- LeetCode 初级算法之数组(上),看看你都学会了吗?
- LeetCode 初级算法之链表,看看你都学会了吗?
- LeetCode 初级算法之字符串(上),看看你都学会了吗?
- 纯代码布局,也可以一样的简洁
- UIStackView之一问一答
- 使用UIStackView来简化iOS的界面布局
- 夏天来了,iOS开发者们该如何减少App耗电?(上)
- 夏天来了,App开发者们如何看待手机发烫问题?
- 聊聊iOS中UITableView复用的那些事
- 曾经经典的微信打飞机游戏还有人记得吗?
- iOS 原生渲染与 Flutter 有什么区别 (上)
- 了解 Mach-O文件
- CocoaPods中podsepc文件设置详解
- iOS 原生渲染与 Flutter 有什么区别 (下)
- 简单了解 iOS CVPixelBuffer (上)
- 谈谈 iOS 包瘦身方案
- 播放器重构的探索之路
- 如何使用CocoaPods制作私有库
- iOS 组件化方案