19

我观看了一些关于数据绑定的 WWDC 视频和 Apple 文档,根据我目前的理解,@State 作为属性委托将提供视图和注释属性之间的绑定连接,例如:

@State var myText: String

var body: some View {
  VStack {
    TextField($myText, placeholder: Text("input"))
    Text(myText)
  }
}

这会将myText与我添加的文本字段的内容绑定(即一个更改另一个将跟进更新)

但是,虽然我知道 $myText 指的是 Binding 的绑定类型,但我注意到 Binding 也是一个属性委托,并且我注意到它出现在 Apple 的一些代码示例中。我不知道这是用作属性委托的。@State 已经完成了绑定工作,那么我们需要 @Binding 做什么呢?苹果文档现在对此感到很糟糕。

4

5 回答 5

17

根据这个 WWDC 谈话(通过 Swift UI 的数据流):

https://developer.apple.com/wwdc19/226

@State应该用于 a 中的本地/私有更改View。理想情况下,它们将是私有的。

@Bindingoutside当值存在于当前视图域时,应该在子视图/可重用组件中使用。

您可以在presentation(:_)API 中看到它。

它们内部可能有一堆状态,告诉SwiftUI如何显示它们 - 但是它是否应该出现的决定取决于超级视图,因此您需要提供@Binding( ) 。isShowing

于 2019-06-07T12:47:09.023 回答
11

@State 只是另一个概述了事实来源的@propertyWrapper 。

“...当您使用状态时,框架会为变量分配持久性存储并将其作为依赖项进行跟踪...您总是必须指定一个初始常量值” -WWDC19 Session 226 (07:41)

@Binding 另一个显式依赖于状态的@propertyWrapper。

“...通过使用 Binding 属性包装器,您可以定义对事实源的显式依赖而不拥有它,此外,您不需要指定初始值,因为绑定可以从状态派生。” - WWDC19 会议 226 (13:01)

在此处输入图像描述 - WWDC19 会议 226

于 2019-06-07T14:16:08.830 回答
5
  • 如果你需要一个属于单个视图的简单属性,你应该使用@State
  • 如果您需要拥有可能属于多个视图(如 2-3 个视图)的复杂属性,则应使用@ObjectBinding
  • 最后,如果您需要拥有需要使用所有周围视图的属性,您应该使用@EnvironmentObject。
于 2019-06-26T06:20:13.997 回答
4

Binding<T>是 的属性委托@Binding

$myText 给你一个Binding<String>.

正如您所描述的那样,@State“进行绑定工作”的方式是为您提供一个Binding<String>使用 getter/setter 进行初始化的方法,该方法捕获State<T>.

现在TextField通过调用传入绑定的 setter 来改变 myText 的值,这反过来又调用State<T>实际设置 myText 的 setter。

如您所见,绑定不需要具有实际存储的属性,它委托给其他具有存储的实例,在本例中为@State. 由此得名。

于 2019-06-26T05:53:13.290 回答
3

@State 已经完成了绑定工作,那么我们需要 @Binding 做什么

@State不会自己创建绑定。它有一个public var binding: Binding<Value>属性(文档):

使用绑定在视图及其底层模型之间创建双向连接。

(在你的情况下String和之间TextField

因此,binding来回绑定值的状态以及@State用于读取和改变值的使用它提供了binding它存储的值。

于 2019-06-07T08:12:39.680 回答