State 如何从视图主体内部更新视图的复杂模型

State 如何从视图主体内部更新视图的复杂模型,state,swiftui,State,Swiftui,我正在构建一个带有大型复杂模型的自定义视图结构,我希望从var body:some View{…}属性中更新该结构(例如,点击视图中表示表列的按钮应更改表中行的排序顺序)。我不允许从body内修改此模型,因为self是不可变的,但是: struct MyTable : View { struct Configuration { // a LOT of data here, ie header, rows, footer, style, etc mutating fun

我正在构建一个带有大型复杂模型的自定义视图结构,我希望从
var body:some View{…}
属性中更新该结构(例如,点击视图中表示表列的按钮应更改表中行的排序顺序)。我不允许从
body
内修改此模型,因为
self
是不可变的,但是:

struct MyTable : View {

  struct Configuration {
     // a LOT of data here, ie header, rows, footer, style, etc

     mutating func update() { ... } // this method must be called before view render
  }
  var configuration : Configuration

  var body : some View {
    // build the view here based on configuration
    self.configuration.columns[3].sortAscending = false // error, `self` is immutable
    self.configuration.update() // error, `self` is immutable
  }
}
我真的不想为所有配置数据创建@State变量,因为1)有很多配置数据,2)很难用这种方式对模型建模

我尝试将
configuration
设置为@State变量,但我无法在
init()
时间设置配置对象,即使代码已编译并运行!(顺便说一句,
configuration
var现在需要在init之前初始化,否则我会在
self.configuration=c
行上得到一个错误,即在初始化所有成员之前使用
self
——这可能是使用@State属性包装器的一个复杂问题。)


我想出了一个解决办法,在
MyTable.init()
中不需要调用
update()
,方法是在
Configuration
中创建一个自定义
init()
来调用
update()
。这样,
MyTable
中的
init()
就没有必要了,这种方法解决了以前遇到的所有问题:

struct MyTable : View {

  struct Configuration {
     ...

     init(...) {
         ...
         self.update()
     }

     mutating func update() { ... } // this method must be called before view render
  }

  @State var configuration : Configuration // note that this property can't be marked private because we want to inject `configuration` at init

  var body : some View {
    // build the view here based on configuration
    self.configuration.columns[3].sortAscending = false // ok, no error now about mutating a @State var
    self.configuration.update() // ok, no error
    ...
  }
}
然后在我的呼叫代码中:

return MyTable.init(configuration: MyTable.Configuration.init(...))

只有与视图相关的变量需要在
主体内更新
。视图是基于配置(即模型)构建的。这是对
@State
的意外使用。对于您描述的用例,您需要基于
observeObject
的ViewModel模式。我尝试在init时将模型注入视图。
return MyTable.init(configuration: MyTable.Configuration.init(...))