@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗?

2023-12-05

当我第一次在 Google 上搜索“State vs ObservedObject”时result来自《Hacking with Swift》,它说的是@ObservedObject:

这与 @State 非常相似,只不过现在我们使用外部引用类型而不是简单的本地属性(如字符串或整数)。

我可以用吗@ObservedObject创建持久状态?是不是这么简单@State用于简单的属性和@ObservedObject适用于复杂的物体,或者还有更多细微差别吗?


@ObservedObject不持久化状态

我可以用吗@ObservedObject创建持久状态?

就其本身而言,你不能。苹果文档有这个要说的@State:

给定类型的持久值,视图通过它读取和监视该值。

但我发现没有提到坚持@ObservedObject所以我构建了这个小演示来证实@ObservedObject不持久状态:

class Bar: ObservableObject {
  @Published var value: Int

  init(bar: Int) {
    self.value = bar
  }
}

struct ChildView: View {
  let value: Int
  @ObservedObject var bar: Bar = Bar(bar: 0)

  var body: some View {
    VStack(alignment: .trailing) {
      Text("param value: \(value)")
      Text("@ObservedObject bar: \(bar.value)")
      Button("(child) bar.value++") {
        self.bar.value += 1
      }
    }
  }
}

struct ContentView: View {
  @State var value = 0

  var body: some View {
    VStack {
      Spacer()
      Button("(parent) value++") {
        self.value += 1
      }
      ChildView(value: value)
      Spacer()
    }
  }
}

每当您点击value++按钮,它会导致重新渲染ChildView因为value财产发生变化。当视图由于属性更改而重新呈现时,它是@ObservedObjects 被重置

screenshot

相反,如果添加一个@State变量为ChildView您会注意到,当@ObservedObject已重置。

使用持久状态@ObservedObject

保持状态@ObservedObject,实例化具体ObservableObject with @State在父视图中。因此,要修复前面的示例,请像这样:

struct ChildView: View {
  let value: Int
  @ObservedObject var bar: Bar  // <-- passed in by parent view

  var body: some View {
    VStack(alignment: .trailing) {
      Text("param value: \(value)")
      Text("@ObservedObject bar: \(bar.value)")
      Button("(child) bar.value++") {
        self.bar.value += 1
      }
    }
  }
}

struct ContentView: View {
  @State var value = 0
  @State var bar = Bar(bar: 0)  // <-- The ObservableObject

  var body: some View {
    VStack {
      Spacer()
      Button("(parent) value++") {
        self.value += 1
      }
      ChildView(value: value, bar: bar).id(1)
      Spacer()
    }
  }
}

类的定义Bar与第一个代码示例相比没有变化。现在我们看到即使在value属性变化:

screen shot

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗? 的相关文章

  • 导航栏隐藏在 SwiftUI 中不起作用

    我有三观 我想隐藏第三个视图中的导航栏 即使我给 navigationBarHidden true 导航栏正在显示 我找不到我哪里做错了 我已在下面附上我的代码和生成的屏幕截图 Xcode 版本 11 1 struct ContentVie
  • Swift UI 导出画布内容

    我有一个画布 用户可以在上面画东西 我想导出用户在画布上绘制的任何内容 并且我正在使用以下扩展从视图中获取图像 extension View func snapshot gt UIImage let controller UIHosting
  • SwiftUI - 使用“ObservableObject”和@EnvironmentObject 有条件地显示视图

    我想在我的应用程序中有条件地显示不同的视图 如果某个布尔值为 true 则将显示一个视图 如果为 false 将显示不同的视图 该布尔值位于 ObservableObject 类中 并根据将要显示的视图之一进行更改 PracticeStat
  • SwiftUI 关闭多个模态表

    我在用 sheet isPresented self showModal 在我的根视图中呈现一个模式 在模态中 我正在使用NavigationView引导用户浏览各个页面 对于用户配置文件构建器 在导航堆栈的最后一页中 我正在使用 Envi
  • 如何使用 SwiftUI 拖动工作滑块

    我想拖动一个滑块 当然也让它滑动 我可以做其中之一 但我不能两者都做 如何拖动并拥有可用的滑块 我也尝试找到一种方法来删除手势 但我找不到方法来做到这一点 还尝试了 Apple Composition SwiftUI Gestures 文档
  • 剪裁为形状的 SwiftUI 图像在上下文菜单中具有透明填充

    在我的 SwiftUI 应用程序中 我的资产目录中有一张宽高比为 1 1 的图像 在我的代码中 我有一个Image使用不同的宽高比查看 将图像裁剪为新尺寸 Image My Image resizable aspectRatio conte
  • Xcode 11 beta swift ui 预览未显示

    只是使用 Swift UI 基本应用程序 即使我处于画布模式 预览画布也不会显示 应用程序运行 我有这个小片段 我错过了什么 if DEBUG struct ContentView Previews PreviewProvider stat
  • 在 iOS 上将 SwiftUI 视图转换为 PDF

    我用 SwiftUI 画了一些漂亮的图表 因为它非常简单且容易做 然后我想将整个 SwiftUI 视图导出为 PDF 以便其他人可以以良好的方式查看图表 SwiftUI 没有直接为此提供解决方案 Cheers Alex 经过一番思考 我想到
  • 在 HStack 中以正确的方式对齐两个 SwiftUI 文本视图

    我有一个包含两行的简单列表视图 每行包含两个文本视图 查看一和查看二 我想对齐每行中的最后一个标签 查看两个 以便名称标签领先对齐并保持对齐 无论字体大小如何 第一个标签 查看一个 也需要前导对齐 我尝试在第一个标签 查看一个 上设置最小框
  • 得到“致命错误:索引超出范围”:在 swiftui 的列表项中显示索引

    更新 错误 类型 没有成员 1 如果在list foreach中放置一个if闭包 if self showMarkedOnly name marked 为什么 代码版本4 struct Name Identifiable Hashable
  • SwiftUI 中的计算 (NSObject) 属性不会更新视图

    所以 我想要一个Text它根据我的 CoreData 模型的内容更改其内容 为此 我在 Xcode beta 4 中使用了计算属性 但它似乎不再起作用了 这是一个错误还是还有其他我没有看到的问题 我真正遇到的问题是我的视图 和计算的属性 似
  • 使用 Firebase/Analytics pod 时 SwiftUI 预览不起作用

    似乎在将 Xcode 12 更新到 beta 5 后 使用 Firebase Analytics pod 时 SwiftUI 预览不再工作 预览失败并出现错误 linker command failed with exit code 1 u
  • 从代码覆盖率中排除 SwiftUI 预览?

    我无法将代码覆盖率提高到最低限度 90 因为 XCode 考虑了 PreviewProvider 我应该怎么办 删除所有 SwiftUI 预览 或者有没有办法可以排除一些带有 PreviewProvider 关键字等的行 Xcode 版本
  • 如何在 SwiftUI 中动态隐藏导航后退按钮

    我需要暂时地在异步操作期间隐藏视图中的后退按钮 我想防止用户在操作完成之前离开视图 隐藏它是可能的永久使用 navigationBarBackButtonHidden true 但是 显然用户在这种情况下无法返回 因此他们被卡住了 我缺少什
  • SwiftUI 多行文本背景颜色

    我在 SwiftUI 中有一个包含多行的文本视图 我知道我可以更改文本的背景颜色 Text
  • SwiftUI 表单中的动态行高

    我正在向 SwiftUI 表单添加控件以帮助用户输入数据 并限制条目 尽管 Forms 有很多值得喜欢的地方 但我发现在该容器之外运行良好的东西在容器内却会发生非常意想不到的事情 并且如何弥补这一点并不总是显而易见的 计划是将数据字段显示为
  • SwiftUI - ForEach 与 Stride

    我试图创建一个 Hstack d 卡列表 也就是说 我想创建一系列行的滚动视图 每行将包含一个 HStack 其中两个视图并排显示 并由某种列表数据结构初始化 struct MyHStackView View var myArray Som
  • 如何在 SwiftUI 中将阴影应用于内部视图?

    我在周围添加了阴影VStack其中包含我的两个文本字段和一个提交按钮 然而 阴影也被应用到了文本框内的两个文本字段 VStack 我在这里缺少什么导致这种情况发生吗 我尝试添加shadow radius 0 在文本字段上 但它不会改变任何内
  • 如何在 SwiftUI 中仅使用 ForEach 而不是列表来滑动删除

    我正在 SwiftUI 中使用 ForEach 制作自定义列表 我的目标是进行滑动删除手势 而不是将 ForEach 嵌入到列表中 到目前为止 这是我的代码 import SwiftUI struct ContentView View le
  • 当我输入字符时,SwiftUI 中的 TextField 失去焦点

    当我在文本字段中输入字符时遇到问题 在练习集视图 我必须重新单击文本框才能输入另一个字符 如果我从文本字段中删除绑定 我可以流畅地输入文本 我认为这与我的演讲者班级和更新集函数重新创建一个集合实例 因为我必须替换数组中两层深处的一些值 Co

随机推荐