Hey, I have a situation where the app freezes (because it's stuck in an endless update cycle) when I pass down a binding to a NavigationPath
.
I have a simple example to reproduce the behavior. Copy the following code and run it in previews, a simulator or a real device. Just tap "Show Middle View" and then "Show Inner View", which will cause the app to freeze, because SwiftUI gets stuck in an update cycle:
import SwiftUI
// This is literally empty
@MainActor final class SomeEnvironmentObject: ObservableObject {}
@MainActor
final class Router: ObservableObject {
@Published var path: NavigationPath = .init()
}
struct ContentView: View {
@StateObject var router = Router()
var body: some View {
NavigationStack(path: $router.path) {
Button("Show Middle View") {
router.path.append(0)
}
.navigationDestination(for: Int.self) { destination in
MiddleView(path: $router.path)
}
}
}
}
struct MiddleView: View {
@EnvironmentObject var someEnvironmentObject: SomeEnvironmentObject
@Binding var path: NavigationPath
var body: some View {
Button("Show Inner View") {
path.append("0")
}
.navigationDestination(for: String.self) { destination in
InnerView(path: $path)
}
}
}
struct InnerView: View {
@Binding var path: NavigationPath
var body: some View {
Text("Inner View")
}
}
#Preview {
ContentView()
.environmentObject(SomeEnvironmentObject())
}
The strange thing is, that the app freezes only, when MiddleView
has the environment object:
struct MiddleView: View {
@EnvironmentObject var someEnvironmentObject: SomeEnvironmentObject
// ...
}
Removing that line makes everything work.
I'm pretty sure this is some kind of navigation dependency problem, where I'm capturing too much in the navigationDestination
modifier, causing SwiftUI to repeatedly update the views in a cycle. I've read about something similar here: https://hachyderm.io/@teissler/112533860374716961
However, I've tried a variety of combinations of only capturing stuff that's needed in the navigationDestination
closure, but nothing works. It still freezes up.
Does anyone have an idea? I assume it's an error on my side, but maybe it could be a bug in SwiftUI? I have no idea how to solve this.
This problem occurs on Xcode 16.0 Beta 5, 16.1 Beta 1 and 15.4, as well as on iOS 17 and iOS 18