Destination view immediately pops back
denizdogan opened this issue · 6 comments
In one of my SwiftUI views, I end the body with:
.task {
pilot.push(.Feed)
}
That causes the navigation stack to pop to the previous path. However, the following works fine:
.task {
// sleep for 3 seconds
try! await Task.sleep(nanoseconds: 3 * NSEC_PER_SEC)
pilot.push(.Feed)
}
Additionally, the following doesn't work:
.task {
// sleep for 0.1 seconds
try! await Task.sleep(nanoseconds: UInt64(0.1) * NSEC_PER_SEC)
pilot.push(.Feed)
}
So I guess there's some timing/threading issues going on here, but I don't know what it is. Any ideas?
I'm guessing this is caused by the well-known NavigationLink issues in SwiftUI, for example: https://developer.apple.com/forums/thread/677333
Seems like that linked issue is causing it as UIPilot is just a nice wrapper around NavigationView and NavigationLink. I will check the issue, can you push the minimal code that's causing the issue somewhere?
@jimmy0251 It seems harder than I expected to reproduce this in a fresh project. I will try to find some time to reliably reproduce this for you.
@jimmy0251 I got a small example working here: https://github.com/denizdogan/NavigationLink-Bug
The bug is that I expect to land on ViewD, but it stops at ViewC -> ViewD -> ViewC
Looks like it's the exact issue you mentioned.
I converted your sample code into pure NavigationUI code and the issue still persists
struct ContentView: View {
var body: some View {
NavigationView {
ViewA()
}
}
}
struct ViewA: View {
@State var isActive = false
var body: some View {
VStack {
NavigationLink(isActive: $isActive, destination: { ViewB() }, label: { EmptyView() })
.isDetailLink(false)
Text("A")
.padding()
.task {
isActive = true
}
}
}
}
struct ViewB: View {
@State var isActive = false
var body: some View {
VStack {
NavigationLink(isActive: $isActive, destination: { ViewC() }, label: { EmptyView() })
.isDetailLink(false)
Text("B")
.padding()
.task {
isActive = true
}
}
}
}
struct ViewC: View {
@State var isActive = false
var body: some View {
VStack {
NavigationLink(isActive: $isActive, destination: { ViewD() }, label: { EmptyView() })
.isDetailLink(false)
Text("C")
.padding()
.onAppear {
isActive = true
}
}
}
}
struct ViewD: View {
var body: some View {
Text("D")
.padding()
}
}
Looks like a timing issue to me. The issue disappears if I replace task
with onAppear
on both View A and B.
I think the best thing we can do now is try some workaround, until the issue is officially fixed from apple side.
@jimmy0251 Thanks for taking the time to investigate it. Let's cross our fingers for a clean solution to this soon.