SwiftUI 嵌套视图偏好详解及锚点其他用法
2023-12-18 13:59:45
导语
在 SwiftUI 的前一部分中,我们介绍了 SwiftUI 的锚点偏好。现在我们终于要走出迷雾森林了。在这最后一部分,我们将把所有的东西组合到一起。我们还将学习 SwiftUI 如何处理嵌套视图的偏好,以及 Anchor 的一些其他用法。如常,先例为敬:
迷你地图显示了表单的微缩形式。不知道我是不是只有一个这样:我喜欢先看到整体,然后放大细节。所以在开始之前,我想给你看看我们最后能做出什么:
[图片]
每个字段都连接到它的标签,不管它的位置如何。黑色圆点是锚点。这很像我们在前面学过的 alignmentGuide
,但稍有不同。让我们把它们分开来看看。
嵌套视图的偏好设置
你可能已经注意到,除了红色的锚点之外,还有一个绿色锚点。我们先来看看它。以下代码创建了嵌套视图的偏好设置:
struct PreferenceKeyToExtractOffset: PreferenceKey {
static var defaultValue: Anchor<CGPoint>.Offset? = nil
static func reduce(value: inout Anchor<CGPoint>.Offset?, nextValue: Anchor<CGPoint>.Offset?) -> Anchor<CGPoint>.Offset? {
return nextValue
}
}
extension View {
func offsetPreference(to key: PreferenceKeyToExtractOffset) -> some View {
background {
GeometryReader { geo in
Color.clear.preference(key: key, value: geo.frame(in: .global).origin)
}
}
}
}
这个代码做了一些有趣的事情。首先,它创建了一个新的 PreferenceKey
叫做 PreferenceKeyToExtractOffset
。这个键用于从嵌套视图中提取 Anchor<CGPoint>.Offset
的值。
然后,它创建了一个扩展视图的 offsetPreference
方法。这个方法允许我们把一个视图的偏移量作为另一个视图的偏好值。在我们的例子中,我们将 Form
视图的偏移量作为 MiniMapView
视图的偏好值。
最后,我们在 Form
视图中使用 offsetPreference
方法来提取 Form
视图的偏移量,并将它作为 MiniMapView
视图的偏好值。
Anchor 的其他用法
除了用于嵌套视图的偏好设置之外,Anchor 还可以用于其他一些目的。这里列出了一些常见的用法:
- 对齐视图: 我们可以使用 Anchor 来对齐视图。例如,以下代码将把
label
视图和textField
视图对齐:
HStack {
label
.frame(width: 100, alignment: .trailing)
textField
.frame(width: 200, alignment: .leading)
}
.anchorPreference(key: HorizontalAlignmentKey.self, value: .trailing, alignment: .leading)
- 定位视图: 我们可以使用 Anchor 来定位视图。例如,以下代码将把
button
视图定位在屏幕的右下角:
VStack {
Spacer()
HStack {
Spacer()
button
.frame(width: 100, height: 100)
}
}
.anchorPreference(key: VerticalAlignmentKey.self, value: .bottom, alignment: .bottom)
- 调整视图的大小: 我们可以使用 Anchor 来调整视图的大小。例如,以下代码将把
label
视图的大小调整为与textField
视图相同:
HStack {
label
textField
.frame(maxWidth: .infinity)
}
.anchorPreference(key: SizeKey.self, value: .width, alignment: .trailing)
结语
Anchor 是 SwiftUI 中一个非常强大的工具。我们可以用它来创建各种复杂的布局。在本文中,我们学习了如何使用 Anchor 来创建嵌套视图的偏好设置,以及 Anchor 的一些其他用法。希望这些知识能帮助你更好地理解 SwiftUI 的布局系统,并创建出更美观、更实用的应用程序。