title: SwiftUI observedobject with dynamic fields
body: <p>I am new to SwiftUI. I have an object that has various properties that I want to bind to fields in the UI. However, the UI is dynamically created. As in, the fields to include and what order can be customized.</p>
  <p>Having trouble getting the UI to refresh when the object is updated (for example, when the user enters a zip code, we automatically populate the city and state fields) I have created a simplified sample.</p>
  <p>I can get it to work by handling each individual field when creating the <code>TextField</code>, but would like to see if it is possible to be more generic.</p>
  <p>Here is the sample object that the UI is displaying the properties</p>
  <pre><code>class TestObject: ObservableObject {
      @Published var testForeignKeyId: Int = 0
      @Published var city: String = &quot;&quot;
      @Published var state: String = &quot;&quot;
      @Published var zip: String = &quot;&quot;
      
      func getStringValue(field: String) -&gt; String {
          switch field {
          case &quot;City&quot;:
              return self.city
          case &quot;State&quot;:
              return self.state
          case &quot;Zip&quot;:
              return self.zip
          default:
              return &quot;&quot;
          }
      }
      
      func getIntValue(field: String) -&gt; Int {
          switch field {
          case &quot;TestForeignKeyId&quot;:
              return self.testForeignKeyId
          default:
              return 0
          }
      }
  }
  </code></pre>
  <p>Sample field struct:</p>
  <pre><code>struct TestField: Identifiable {
      let id = UUID().uuidString
      var label: String
      var fieldType: String
  }
  </code></pre>
  <p>It works if I do this and handle each field:</p>
  <pre><code>struct ContentView: View {
      @ObservedObject var obj: TestObject
      var fields: [TestField] = []
      @State var stringValue = &quot;&quot;
      
      init() {
          self.fields = [TestField(label: &quot;City&quot;, fieldType: &quot;Text&quot;), TestField(label: &quot;State&quot;, fieldType: &quot;Text&quot;), TestField(label: &quot;Zip&quot;, fieldType: &quot;Zip&quot;)]
          self.obj = TestObject()
      }
  
      var body: some View {
          List {
              ForEach(self.fields) { field in
                  Text(field.label)
                  switch field.label {
                  case &quot;City&quot;:
                      TextField(&quot;&quot;, text: $obj.city)
                  case &quot;State&quot;:
                      TextField(&quot;&quot;, text: $obj.state)
                  case &quot;Zip&quot;:
                      TextField(&quot;&quot;, text: $obj.zip,
                                onEditingChanged: { edit in
                                  if !edit {
                                      // lookup values for zip
                                      self.obj.city = &quot;Test&quot;
                                      self.obj.state = &quot;TT&quot;
                                  }
                                })
                  default:
                      Text(field.label)
                  }
              }
          }
      }
  }
  </code></pre>
  <p>Would like to be able to do something like this and create the text fields based on the <code>fieldtype</code> instead of the individual fields (since the actual object has many more properties):</p>
  <pre><code>                switch field.fieldType {
                  case &quot;Text&quot;:
                      Text(field.label)
                      TextField(&quot;&quot;, text: self.obj.getStringValue(field: field.label))
                  case &quot;Zip&quot;:
                      Text(field.label)
                      TextField(&quot;&quot;, text: self.obj.getStringValue(field: field.label))
  
                  }
  </code></pre>
  <p>But when I do that, I get the error:</p>
  <p>Cannot convert value of type <code>String</code> to expected argument type <code>Binding&lt;String&gt;</code></p>
  <p>I also tried using a state variable like</p>
  <p><code>@State var stringValue = &quot;&quot;</code></p>
  <p>Then in the .onAppear of the text field, I assigned the value of the appropriate property (<code>obj.state</code> etc) to the <code>stringValue</code> state variable. I thought that maybe the control would refresh if the <code>observedObject</code> was updated, but couldn't figure out where to update the <code>stringValue</code> state variable to get it working.</p>
  <p>Hopefully I explained what I'm trying to do well enough. Does anyone have an idea on how to get it working?</p>
  <p>Thanks</p>