ios - 为什么 GeometryReader 的主体会被评估两次?也是第一次尺寸为零?
问题描述
我有一个嵌套在 NavigationView 中的 GeometryReader。在 GeometryReader 内部,我使用 GeometryProxy 提供的尺寸和 if 语句。在我的项目中,我偶然发现了一个事实,即 GeometryReader 中的内容被评估了两次,并且第一次提供的尺寸是宽度 0 和高度 0。此外,if case 内的内容的 onAppear() 方法被调用两次,这会导致更多问题。
有人可以解释这种行为,以便我可以改进我的代码吗?
我做了一个最小的例子来展示这个问题:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView() {
NavigationLink(destination: SecondView()) {
Text("Click me!")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct SecondView: View {
private func showHorizontal(_ w: CGFloat, _ h: CGFloat) -> Bool {
print("Dimensions \(w), \(h)")
return (w > h)
}
var body: some View {
GeometryReader { proxy in
if self.showHorizontal(proxy.size.width, proxy.size.height) {
Text("Landscape")
.onAppear() {
print("Landscape appeared")
}
} else {
Text("Portrait")
.onAppear() {
print("Portrait appeared")
}
}
}
.onAppear() {
print("GeometryReader appeared")
}
}
}
在横向的 iPad 上,我得到以下控制台输出:
Dimensions 0.0, 0.0
Dimensions 1194.0, 688.0
GeometryReader appeared
Landscape appeared
Landscape appeared
解决方案
GeometryReader
正在更新其几何形状的变化,这是有道理的。在您的 if 子句中,您正在为Text
每个评估创建一个新视图。你所看到的是这些onAppear
中的每一个。
if self.showHorizontal(proxy.size.width, proxy.size.height) {
Text("Landscape")
.onAppear() {
print("Landscape appeared")
}
}
如果出于某种原因需要 Text 保持不变,则可以使用id 修饰符为其分配一个 id ,如下所示:
if self.showHorizontal(proxy.size.width, proxy.size.height) {
Text("Landscape")
.id("fixed id")
.onAppear() {
print("Landscape appeared")
}
}
推荐阅读
- sql - 我需要对 (Account No_) 列的计数求和,并得到高于 2 的结果
- c# - 实体框架:根据父实体上的值对子实体进行索引以实现唯一性
- python - 到 CSV 的元组列表
- angular - Angular 7 编译突然失败
- flyway - Flyway 的多个配置文件
- python - 使用 Quarter 将时间戳字符串解析为 Python 日期时间
- vb.net - 文本框格式转换为日期时间?
- asp.net-core - 在 Asp 核心 web api 和 angular8 中上传图像的问题
- android - 安卓。在 Light Theme 中使用深色主题颜色
- android - JSON 对象后截击请求无法发送,显示截击失败消息