Search code examples
swiftswiftuiclosuresviewbuilder

Set a @State var inside an If statement in Swift


I am trying to set the value of a @State var in an If statement that is inside of a struct of type :View, like so:

struct Name: View {
  @State someVar: Int = 0
    var body: some View {
      VStack {
        if this > that {
          someVar = 1

But when I do this I get the error: "Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols". If I use a class method that does what I need, like this:

    if this > that {       
      someClass.doIt()
    }

I get the same error.

What is the right way to do this?


Solution

  • You cannot put logic code like that inside your body -- all that you can have there is code that outputs a view.

    So, you could do:

    var body: some View {
      if this > that {
        Text("This")
      } else {
        Text("That")
      }
    }
    

    because that results in a View (Text) getting rendered. In your example, though, you're just doing assignment.

    That has to be done in a separate function or in a closure outside of what gets directly rendered in the view.

    So:

    func testThisThat() {
      if this > that {
       someVar = 1
      }
    } 
    
    var body: some View {
      Button(action: {
       testThisThat()
      }) {
       Text("Run test")
      }
    }
    

    In the above, your logic runs in a closure outside the view hierarchy, and a Button gets rendered to the view.

    If you give more specifics about what you're trying to do, perhaps the answer can be clarified, but that's the source of the error.

    As suggested in the comments, you can also run logic code in onAppear, like this:

    var body: some View {
      VStack {
       //view code
      }.onAppear {
       //logic
        if this > that {
          someVar = 1
        } 
      }
    }