setting computed property in a SwiftUI view doesn't compile

Viewed 327

Trying to set the computed property s in a SwiftUI view gets compiler error "Cannot assign to property: 'self' is immutable".
How do I have to I call the setter?

struct Test: View{
  @State var _s = "test"
  @State var _s2 = true
  private var s : String
  { get { _s }
    set (new)
    { _s = "no test"
      _s2 = false
      // do something else
    }
  }

  var body: some View
  { Text("\(s)")
    .onTapGesture {
      self.s = "anyting"  // compiler error
    }
  }
}
2 Answers

Aha... I see. Just use non mutating set

  private var s : String
  { get { _s }
    nonmutating set (new)
    { _s = "no test"
      _s2 = false
      // do something else
    }
  }

That is, why you already have @State property wrapper in your View.

struct Test: View{
  @State var s = "test"
    var body: some View {
    Text("\(s)")
    .onTapGesture {
      self.s = "anyting"  // compiler error
    }
  }
}

You able to change s directly from your code because s is wrapped with @State.

this is functional equivalent of the above

struct Test: View{
    let s = State<String>(initialValue: "alfa")
    var body: some View {
        VStack {
            Text("\(s.wrappedValue)")
                .onTapGesture {
                    self.s.wrappedValue = "beta"
            }
        }
    }
}

Or if Binding is needed

struct Test: View{
    let s = State<String>(initialValue: "alfa")
    var body: some View {
        VStack {
            TextField("label", text: s.projectedValue)
        }
    }
}
Related