ios - SwiftUI @State 变量没有被取消初始化

标签 ios swift xcode swiftui combine

我有一个 SwiftUI View ,我在其中声明这样的条件

@State var condition = UserDefaults.standard.bool(forKey: "JustKey")

当我第一次将此 View 插入导航堆栈时,条件变量正在获取正确的值。然后,当我弹出此 View 时,我更改了 UserDefaults 中的值,但是当我再次按下此屏幕时,条件变量会记住它第一次获得的旧值。 如何找到解决方法,因为我想在每次进入声明它的自定义 View 时重新初始化我的条件变量?

最佳答案

在这种情况下,@State 的行为与它应该的完全一样:作为它所附加的组件的持久存储。

从根本上来说,使用 NavigationLink 推送 View 就像 View 层次结构中的任何其他组件一样。屏幕是否实际可见是一个实现细节。虽然 SwiftUI 在关闭屏幕后实际上并未渲染隐藏的 UI 元素,但它确实保留了 View 树。

您可以使用 .id(_:) 修饰符强制完全丢弃 View ,例如:

struct ContentView: View {
  @State var i = 0

  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(destination: DetailView().id(i)) {
          Text("Show Detail View")
        }
        Button("Toggle") {
          self.i += 1
          UserDefaults.standard.set(
            !UserDefaults.standard.bool(forKey: "JustKey"),
            forKey: "JustKey")
        }
      }
    }
  }
}

切换按钮既可以修改 JustKey 的值,又可以增加我们传递给 .id(i) 的值。当 id(_:) 的单数参数发生变化时,id 修饰符告诉 SwiftUI 这是一个不同的 View ,因此当 SwiftUI 运行时,它是diffing 算法它会丢弃旧的并创建一个新的(使用新的 @State 变量)。了解有关 id 的更多信息 here .


上面的解释提供了一种解决方法,但这不是一个好的解决方案,IMO。更好的解决方案是使用 ObservableObject。它看起来像这样:

@ObservedObject condition = KeyPathObserver(\.JustKey, on: UserDefaults.standard)

您可以在 this SO answer 找到实现 KeyPathObserver 的代码和完整的 Playground 示例。

关于ios - SwiftUI @State 变量没有被取消初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59406924/

相关文章:

objective-c - 界面中最好的类别或私有(private)属性是什么

ios - 使用字符串参数实现执行选择器

swift - 如何通知我的 NSFetchedResultsController 我通过 NSBatchUpdateRequest 更改了一些对象?

ios - 当应用程序未处于运行状态(非事件状态)时下载所有推送通知

ios - 如何为 MapView 上的每个自定义注释添加图像?

xcode - 是否可以在 Xcode 中为每个项目(甚至每个文件)设置缩进设置?

iphone - 没有动画的 UIToolbar 过渡

ios - 如何添加前导填充以在 UIStackView 中添加 View

iphone - 如何声明此应用程序的设备功能?

ios - Objective-C 中的所有对象基本上都是指针吗?