0

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?

Duncan C
  • 128,072
  • 22
  • 173
  • 272

1 Answers1

0

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
    } 
  }
}
jnpdx
  • 45,847
  • 6
  • 64
  • 94
  • 1
    I think the OP does not want run an action to execute some code! all OP want checking some logic and then execute some action, which I think onAppear or onChange would be much better options in this case. – ios coder Feb 08 '21 at 21:16
  • 2
    Good point -- updated answer to reflect that. – jnpdx Feb 08 '21 at 21:28
  • Thanks for the clarification. Putting the logic in .onAppear solves my problem. By tagging it onto the VStack it allows me to determine the result of a compare and then pass that into a 'Done' Button that is pressed to dismiss a sheet. I can then do some updating prior to leaving the view. – for coder in woods Feb 09 '21 at 00:17