您当前位置:资讯中心 >其他 >浏览文章

一起聊聊 SwiftUI 布局协议

来源:互联网 日期:2022/12/7 9:01:14 阅读量:(0)

简介

今年 SwiftUI? 新增最好的功能之一必须是布局协议。它不但让我们参与到布局过程中,而且也给了我们一个很好的机会去更好的理解布局在 SwiftUI 中的作用。

早在2019年,我写了一篇文章SwiftUI 中 frame 的表现[1],其中,我阐述了父视图和子视图如何协调形成最终视图效果。那里描述的许多情况需要通过观察不同测试的结果去猜测。整个过程就像是发现外星行星,天文学家发现太阳亮度微小的减少,然后推断出这一定是行星过境(了解行星过境[2])。

现在,有了布局协议,就像用自己的眼睛在遥远的太阳系漫游,令人振奋。

创建一个基础布局并不难,只需要实现两个方法。尽管如此,我们仍然有很多选择去实现一个复杂的容器。我们将会探索常规布局案例之外的内容。有许多有趣的话题到目前为止我还没有在任何地方看到过解释,所以我将在这里介绍它们。然而,在深入这些领域之前,我们需要先打下扎实的基础。

由于涉及到许多内容,我将分成两个部分:

Part 1 - 基础:

  • 什么是布局协议
  • 视图层次结构的族动态
  • 我们的第一个布局实现
  • 容器对齐
  • 自定义值:LayoutValueKey
  • 默认间距
  • 布局属性和 Spacer()
  • 布局缓存
  • 高明的伪装者
  • 使用AnyLayout切换布局
  • 结语

Part 2 - 高级布局:

  • 开启有趣的旅程
  • 自定义动画
  • 双向自定义值
  • 避免布局循环和崩溃
  • 递归布局
  • 布局组合
  • 另一个组合案例:插入两个布局
  • 使用绑定参数
  • 一个有用的调试工具
  • 最后的思考

如果你已经熟悉布局协议,你可能想直接跳到第二部分。这是可以的,尽管我仍然推荐你浏览第一部分,至少浅读一下。这将确保我们在开始探索第二部分中描述的更多高级特性时,我们在同一进度。

如果在阅读本文的任何时候,你认为布局协议不适合你(至少目前来说),我仍然建议你查看 Part2 的这一小节—一个有用的调试工具,这个工具可以帮助你使用 SwiftUI ,且不需要理解布局协议就可以使用。我将它放在第二部分结尾是有原因的,这个工具是使用本文的知识构建的。不过,你可以直接复制代码使用它。

什么是布局协议

采用布局协议类型的任务,是告诉 SwiftUI 如何放置一组视图,需要多少空间。这类型常常被作为视图容器,虽然布局协议是今年新推出的(至少公开来说),但是我们在第一天使用 SwiftUI 的时候就在使用了,当每次使用 HStack? 或者 VStack 放置视图时都是如此。

请注意至少到现在,布局协议不能创建懒加载容器,比如 LazyHStack? 或 LazyVStack。懒加载容器是指那些只在滚入屏幕时渲染,滚出到屏幕外就停止渲染的视图。

一个重要的知识点,Layout? 类型不是视图 。例如,它们没有视图拥有的 body 属性。但是不用担心,目前为止你可以认为它们就是视图并且像视图一样使用它们。这个框架使用了漂亮的 Swift? 语言技巧使你的布局代码在向 SwiftUI 中插入时产生一个透明视图 。我将在后面-高明的伪装者部分说明。

视图层次结构的族动态

在我们开始布局代码之前,让我们重新审视一下 SwiftUI 框架的核心。就像我在以前的文章 SwiftUI 中 frame 的表现 所描述的的那样,在布局过程中,父视图给子视图提供一个尺寸,但最终还是由子视图决定如何绘制自己。然后,它将此传达给父视图,以便采取相应的动作。有三个可能的情况,我们将专注讨论于横轴(宽度),但纵轴(高度)同理:

情况一:如果子视图需求小于提供的视图

在这个例子中考虑文本视图,提供了比需要绘制文字更多的空间

图片

struct ContentView: View {
var body: some View {
HStack(spacing: 0) {

Rectangle().fill(.green)

Text("Hello World!")

Rectangle().fill(.green)

}
.padding(20)
}
}
关键字:
声明:我公司网站部分信息和资讯来自于网络,若涉及版权相关问题请致电(63937922)或在线提交留言告知,我们会第一时间屏蔽删除。
有价值
0% (0)
无价值
0% (10)

分享转发:

发表评论请先登录后发表评论。愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。