尝试用 SwiftUI 写了一个小玩具,在这期间参考了不少书籍,踩了不少坑。在完善玩具的途中,想着写一些文章记录一下。虽然自己 pc 也有有记录,但是传到个人博客上的文章在写的时候还是会费点心思,最起码格式会规范一些,也算是督促自己。 那么就以 SwiftUI Frame 为开篇吧。
Frame
在 UIKit 框架中的 frame 为 UIView 的一个属性,类型为 CGRect
的一个结构体。
而 SwiftUI 中 frame 则是两个函数,一个是不带理想值的版本,一个是有理想值的版本。这里暂且只看不带理想值的简短版本 frame(width:height:alignment:)
,完整的函数声明是这样的:
1 | func frame( |
函数有三个参数且都有默认值,返回值为遵守了 View 协议的不透明类型。
很多 SwiftUI 的书籍上都再三强调了, frame
这个修饰器并没有改变 View 原有的某个属性(比如宽高),而是返回了一个 新具有新属性的 视图 来包装原有的 视图。
上面这句话理解起来有困难,毕竟这也是坑点之一,那么请根据下面这段代码和效果图再来看。
1 | struct FrameView: View { |
首先创建了一个矩形,填充颜色为绿色,接下来到了代码 1 处:frame 设置为宽50,高50,边框黄色;代码 2 处 frame 设置为宽100,高100,边框红色,背景色蓝色; 代码 3 处 frame 设置为宽200,高200,背景色黑色。
效果图中并不是只展示了一个宽300 高300 点黑色矩形。而是展示了三个矩形,分别对应代码 1, 2, 3 。 正如上面所强调的那样, frame 并不是改变了一个视图的某个属性,而是返回了一个具有新属性的视图来包装原有的视图。 在这里代码1调用 frame 生成了一个长宽50的绿色矩形,代码2调用 frame 生成了一个长宽 100 的蓝色矩形,代码3调用 frame 生成了一个长宽200的黑色矩形,它们居中对齐。
实际运用
理解了这一点,看下面这段代码也就好理解多了,是我看 《SwiftUI编程思想》书时看到的。
《SwiftUI编程思想》自定义布局一章中的锚点部分有这么一段代码。
1 | var body: some View { |
这段代码的目的是,根据 tabs 创建一系列的 tab 按钮,点击 按钮时,一个矩形移动到选中的按钮下面。如图:
代码 1 和 2 处都调用了 frame 方法。 代码1 根据选中的 tab 按钮设置了矩形条的宽高,代码2 又再次生成了一个大小和 HStack 一样的视图包裹了 代码1 处生成的视图,并将子视图的对齐方式设置为底部靠左对齐,这才有了正确的效果。
总结
对 SwiftUI 的 frame 有返回和包装的概念就可以正确理解了。技术点并没有大小之分,只有理解和不理解。
参考
文档
swiftwithmajid-Frames in SwiftUI
书籍