40

Apple 关于 SwiftUI 的本教程使用美元符号来绑定数据,我在 SwiftUI 中找不到有关此数据绑定的更多信息。

Toggle(isOn: $showFavoritesOnly) {

您使用 $ 前缀来访问与状态变量或其属性之一的绑定。

这是某种inout类型参数吗?这使用&符号来传递它。

4

2 回答 2

64

这在 WWDC 2019 视频 415 中得到了很好的解释。您只是在查看一种广泛的语言功能的特殊情况,即属性包装器。

属性包装器(例如@State)实际上是一种引用具有相同名称(例如 State)的类型(通常是结构或枚举)的实例的方式。后者提供了将此实例属性转换为计算属性的说明,该计算属性的 getter 和 setter 是其自身的某个计算属性(its wrappedValue)的 getter 和 setter。它通常还拥有支持该计算属性的私有存储。

因此,在声明之后

@State var showFavoritesOnly = true

...showFavoritesOnly转换为计算属性,其 getter 和 setter 由 State 结构提供。当您设置showFavoritesOnly为 true 时,它​​将通过 State 结构的设置器进行路由,并最终在 State 实例的存储属性中。

所有这一切都意味着某处有一个State 实例与您的showFavoritesOnly. 有,但它是隐藏的。如果您想查看该 State 实例,它的名称是_showFavoritesOnly.

好的,但是当您说 时$showFavoritesOnly,您没有得到 State 结构;你得到一个绑定结构。为什么?这是因为属性包装器有一种机制来指定$名称的返回值应该是什么。在 State 的情况下,它指定这个值应该是它自己的binding属性,它是一个 Binding(参见文档:https ://developer.apple.com/documentation/swiftui/state )。

巧合的是,Toggle 的isOn初始化程序采用了 Binding(再次参见文档,https://developer.apple.com/documentation/swiftui/toggle/3232112-init)。即使您isOn愿意,也无法将 Toggle 设置为!showFavoritesOnly相反,您将其设置Binding<Bool>为由 State 实例提供的,以便 Toggle 与 State 对象具有自动双向通信。SwiftUI 框架强制执行自己的正确用法;一个 Toggle 只能存在与作为其开/关状态的基本事实来源的某些绑定有关。而且因为它是一个绑定,而不仅仅是一个 Bool,所以通信是双向的:当用户点击 Toggle 中的开关时,值的变化通过绑定“向上”流向 State 变量。

于 2019-06-12T17:01:42.540 回答
31

$与属性委托一起使用。

不是 operator,而是前缀(感谢@matt!)。

有关属性委托的更多信息,请参阅此 Swift Evolution文档

例如 in @State var aState = falseState是一个属性委托。

这意味着如果我们写:

  • aState我们正在访问一个Bool
  • $aState我们正在访问一个Binding<Bool>

不同的属性委托将生成不同的值。

于 2019-06-11T20:33:26.457 回答