Infinite loop getting "_dismiss changed"

I'm working on a NavigationStack based app. Somewhere I'm using:

@Environment(\.dismiss) private var dismiss

and when trying to navigate to that view it gets stuck.

I used Self._printChanges() and discovered the environment variable dismiss is changing repeatedly. Obviously I am not changing that variable explicitly. I wasn't able to reproduce this in a small project so far, but does anybody have any idea what kind of thing I could be doing that might be causing this issue?

iOS 17.0.3

Have you found a solution?

@gbuela , have you found a solution?

Weirdly enough, for me it happened because I had an array of tuples inside my View.

You don't even have to use the array, just having it in the View was enough to cause the infinite loop:

struct SomeView: View {
  ...
  var sections: [(String, String)] = [
    ("String 1", "value 1"),
    ("String 2", "value 2"),
    ("String 3", "value 3"),
    ("String 4", "value 4")
  ]

  var body: some View {
    ...
  }
}

I have a similar bug. It helped to put the data array inside an ObservableObject. The dismiss variable still seems to change 3-4 times when the view appears but after that it seems to stabilise

I just struggled with this problem for a while -- what has seemed to fix my problem was removing the @State property wrapper from variables that shouldn't have had the wrapper in the first place (Date, Timer...). Always heard that @State should only be used for simpler types but this is the first instance where it really gave me a headache... now I know, hopefully it saves someone else some time.

I am facing the same issue, no idea how to fix it.

Was anyone able to find a solution yet? Thank you

The only thing which seemed to work was to replaced @Environment(.dismiss) var dismiss with the supposedly deprecated @Environment(.presentationMode) var presentationMode to handle my dismissals

I just encountered this out of nowhere. I assumed that some @State variable was changing over and over, so I removed all the @State decorations from member variables.

This did not fix the problem, but it did alter it. Now the view's init() is only called twice in succession, but the view still never appears.

If I get rid of all use of @Environment(.dismiss), I can restore all @States and the invoked view appears as it used to.

I have no idea what triggered this crippling bug.

OK, update: Thanks to @gbuela mentioning Self._printChanges, I discovered the problem in my case. Maybe it will help someone else:

I have a non-@State object in my view, which gets passed to another view through a NavigationLink. Apparently this is another case of SwiftUI prematurely building views that might be invoked. When this object gets passed (by reference, because it's a class) to this particular destination view, that view sets one of its members.

I don't know why the parent view is rebuilding on changes to a non-state member object, though. It wasn't a state in the destination view, either.

I had to eliminate several modifications to the passed object through a sequence of views, because SwiftUI pre-built a stack of them.

SwiftUI's pre-building of views creates copious opportunities for bugs, and pain for developers.

Infinite loop getting "_dismiss changed"
 
 
Q