我正在关注这个SwiftUI 教程 https://developer.apple.com/tutorials/swiftui/handling-user-input并下载了项目文件 https://docs-assets.developer.apple.com/published/e0e45d9449/HandlingUserInput.zip.
我构建并运行了完整的项目,没有进行任何修改。在应用程序中,如果我:
- 在列表视图中切换“仅显示收藏夹”
- 点击“Turtle Rock”或“Chilkoot Trail”详细视图
- 在详细视图中,我切换最喜欢的按钮(黄色星形图标)
屏幕将自动跳回列表视图。
但是,如果我点击列表视图中最后一个项目(“圣玛丽湖”)的详细信息视图,我可以打开和关闭黄色星形按钮,并且仍然保留在相同的详细信息视图中。
谁能解释这种行为?我需要做什么才能留在详细视图中而不被迫导航回列表视图?
好吧,实际上这是 SwiftUI 的缺陷,视图层次结构之外的 View 不能刷新(即body
称为) - 它应该在下次出现后立即更新。 (我提交了反馈#FB7659875,并建议对每个受影响的人做同样的事情 - 当重复更好时就是这种情况)
同时,下面是可能的临时解决方法(不过,即使苹果解决了问题,它也会继续工作,所以它是安全的)。这个想法是使用本地视图状态模型作为视图和已发布属性之间的中间,并使其仅在视图可见时更新。
仅提供了要在上述项目中替换的更正视图。
使用 Xcode 11.4 / iOS 13.4 进行测试 - 没有意外的“跳回”
struct LandmarkList: View {
@EnvironmentObject private var userData: UserData
@State private var landmarks = [Landmark]() // local model
@State private var isVisible = false // own visibility state
var body: some View {
NavigationView {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
Text("Show Favorites Only")
}
ForEach(landmarks) { landmark in
if !self.userData.showFavoritesOnly || landmark.isFavorite {
NavigationLink(
destination: LandmarkDetail(landmark: landmark)
.environmentObject(self.userData)
) {
LandmarkRow(landmark: landmark)
}
}
}
}
.onReceive(userData.$landmarks) { array in // observe external model
if self.isVisible {
self.landmarks = array // update local only if visible
}
}
.onAppear {
self.isVisible = true // track own state
self.landmarks = self.userData.landmarks
}
.onDisappear { self.isVisible = false } // track own state
.navigationBarTitle(Text("Landmarks"))
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)