代码之家  ›  专栏  ›  技术社区  ›  Nickofthyme

将`@Environment`值分配给`Binding`参数

  •  1
  • Nickofthyme  · 技术社区  · 1 年前

    我正在创建一个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 类I可以更新值,并使更新反映在所有使用中。

    分配的最佳方式是什么 @可观察 @Environment 类属性到 结合 参数

    1 回复  |  直到 1 年前
        1
  •  1
  •   jnpdx    1 年前

    使其成为 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