我正在创建一个MacOS应用程序,希望将应用程序的状态存储在内存中,并将其传递给几个组件,但也要从这些组件更新状态.

import SwiftUI

@Observable
class Book {
  var title: String
  
  init(_ title: String) {
    self.title = title
  }
}

struct ParentView : View {
  @State private var myBook = Book("First title")
  
  var body: some View {
    VStack {
      Text("Book title (Parent): \(myBook.title)")
      
      ChildView()
        .frame(width: 200, height: 100)
        .background(.teal)
        .environment(myBook) // Add myBook to environment
    }
  }
}

struct ChildView : View {
  @Environment(Book.self) var myBook: Book
    
  var body: some View {
    VStack {
      Text("Book title (Child): \(myBook.title)")
      
      TextField("Book title", text: myBook.title) // Error here!!!
    }
  }
}

当我试图将myBook.title作为Binding传递给TextField时,这会引发错误.

Cannot convert value of type 'String' to expected argument type 'Binding<String>'

enter image description here

这是有道理的,但通常情况下,因为Book是一个@Observable类,所以我可以更新值,并让更新反映在所有用法中.

@Observable @Environment类属性赋给Binding参数的最佳方式是什么?

推荐答案

如果你想得到Binding,你需要使用Bindable:

struct ChildView : View {
  @Environment(Book.self) var myBook: Book
    
  var body: some View {
    VStack {
      Text("Book title (Child): \(myBook.title)")
      
      @Bindable var myBook = myBook
      TextField("Book title", text: $myBook.title)
    }
  }
}

文档(包括类似的示例):https://developer.apple.com/documentation/swiftui/bindable

Swift相关问答推荐

对多个项目的数组进行排序

MyApp类型不符合协议App''''

字符串目录不适用于SWIFT包

如何在init()中使用setter/getters?

SwiftUI:使视图B与视图A具有相同宽度的视图A更改比率?

如何在visionOS中进行购买?&# 39;购买(选项:)在visionOS中不可用

如何异步返回视图?什么?

有没有办法让文本字段以不同的 colored颜色 显示而不影响半透明背景?

如何在 SwiftUI 中创建条件内容?

macOS 的窗口框架中使用的真实类型和真实类型是什么?

SwiftUI Grid 中的数组旋转

使用 Swiftui 水平修剪 Shape()

Vapor 4,如何按外键过滤?

VStack SwiftUI 中的动态内容高度

无法从自定义动态框架(Swift)访问类

NSFontAttributeName 已更改为 String

swift 3 错误:参数标签 '(_:)' 不匹配任何可用的重载

更改在变量的 willSet 块中设置的值

键盘显示时Tableview滚动内容

Swift 中的单元测试致命错误