105

I was working on an application with login and after login there are categories listed. And under each category there are some items listed horizontally. The thing is after login, main page appears and everything is listed great. When you click on an item it goes to detailed screen but when you try to go back it just crashes. I found this flow Why does my SwiftUI app crash when navigating backwards after placing a `NavigationLink` inside of a `navigationBarItems` in a `NavigationView`? but i could not solve my problem. Since my project become complicated, I just wanted to practice navigation in swiftui and I created a new project. By the way I downloaded the latest xcode version 11.3. I wrote a simple code as follows:

NavigationView{
        NavigationLink(destination: Test()) {
            Text("Show Detail View")
        }
    .navigationBarTitle("title1")

And Test() view is as follows:

import SwiftUI

struct Test: View {
    var body: some View {
        Text("Hello, World!")
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        Test()
    }
}

As you can see it is really simple. I also tried similar examples on the internet but it does not work the way it suppose to work. When I run the project, I click the navigation link and it navigates to Test() view. Then I click back button and it navigates to the main page. However, when I click the navigation link second time, nothing happens. Navigation link works only once and after that nothing happens. It does not navigate, it des not throw any error. I am new to swiftui and everything is great but the navigation. I tried many examples and suggested solutions on the internet, but nothing seems to fix my issues.

C.Aglar
  • 1,290
  • 2
  • 14
  • 30
  • 2
    version of xCode 11.2 (11B52), this code works as expected on both the canvas and the device – Hrabovskyi Oleksandr Dec 11 '19 at 05:31
  • 3
    Tested your code snapshot with Xcode 11.2 / iOS 13.2 - works well. Try to downgrade Xcode. – Asperi Dec 11 '19 at 05:31
  • 1
    Xcode version 11.2.1 (11B500) your code works as it must. – Nalov Dec 11 '19 at 10:19
  • 2
    I sent a review to Apple, it remains to wait for a future update – Hrabovskyi Oleksandr Dec 11 '19 at 11:42
  • Thank you for your comments. I had a similar code in 11.2 and it was working. I think it is a 11.3 issue but I do not understand why these kinds of issues keep happening on swiftui navigation feature. And I cannot find the correct way to implement it. – C.Aglar Dec 11 '19 at 22:22
  • Just sent a report to Apple too. I thought I was going mad; this is the first time I'm trying to use this approach. – Darren Black Dec 17 '19 at 15:57
  • Spent a couple of hours this morning on the same problem, till I realised that the problem is in Xcode version :| – EvZ Dec 19 '19 at 11:08
  • I have the same problem, the code fails in Simulator 13.3 (17C45) but it works on the phone 13.3 (17C54). Rhetorical questions to Apple, why aren't you releasing simulators with the current production release? Apple, how do you expect us to release on this platform when core/basic functionality can't be tested on a simulator, this isn't beta anymore... – J. Edgell Dec 21 '19 at 23:23
  • 1
    Sent bug report FB7518930 – Pacu Jan 03 '20 at 20:17
  • Fixed in Xcode Version 11.4 beta (11N111s) – ozmpai Feb 11 '20 at 12:59

5 Answers5

65

[UPDATE] Nov 5, 2020 - pawello2222 says that this issue has been fixed in Xcode 12.1.


[UPDATE] Jun 14, 2020 - Quang Hà says that this issue has come back in Xcode 11.5.


[UPDATE] Feb 12, 2020 - I checked for this issue in Xcode 11.4 beta and found that this issue has been resolved.


I was getting the same issue in my project too, when I was testing it in Xcode's simulator. However, when I launched the app on a real device (iPhone X with iOS 13.3), NavigationLink was working totally fine. So, it really does seem like Xcode's bug.

Sagun Raj Lage
  • 2,326
  • 2
  • 18
  • 28
  • 19
    exactly same for me. I'm starting to regret having chosen Swiftui for a new app – theMouk Jan 09 '20 at 15:41
  • 14
    i just spent 4 hours feeling very stupid... This stuff is not production ready... – Sebastian Jan 17 '20 at 10:26
  • SwiftUI is still basically version 1.0 Do you ever plan on using v 1.0 of anything for a production release? You start with it with the expectation that it will improve. This doesn't help if you need to release before that happens. – David Reich Jan 19 '20 at 02:28
  • @DavidReich if SwiftUI was in beta, I could understand there would be lots of issues. In production ready tooling, the least one have to expect is that it works. There has been several "point updates" of iOS and macOS since the initial release last year, so glaring bugs like this or the "jumping list title bug" should have been squashed long time ago. I tried to use it for a production app, but had to go back to UIKit to get a decent result. – GJ Nilsen Jan 20 '20 at 09:41
  • @GJNilsen They "should" work as expected. When was the last time v1.0 of anything from Apple, Microsoft, etc. was without significant bugs? You and I can't get away with that, but they can. – David Reich Jan 24 '20 at 01:13
  • Confirming that it's still an issue on Xcode 11.3.1 and it works fine if you use your phone instead of the emulator. – Soja Jan 28 '20 at 16:19
  • It works for iOS, but not for a tvOS device running 13.3. I'm loosing track of what works and what doesn't in the SwiftUI ecosystem. :D – malte Feb 01 '20 at 11:41
  • 3
    [UPDATE] Feb 12, 2020 - I checked for this issue in Xcode 11.4 beta and found that this issue has been resolved. – Sagun Raj Lage Feb 14 '20 at 04:25
  • @SagunRajLage: XCode 11.5 appears again – Quang Hà Jun 13 '20 at 19:03
  • @QuangHà thank you for the update! I've updated the answer based on your comment. :) – Sagun Raj Lage Jun 14 '20 at 08:41
  • Yep, it's back at least on the simulator, has anyone checked on a device? – Zorayr Jun 18 '20 at 06:15
  • @pawello2222, thank you! I've updated the answer based on your comment. – Sagun Raj Lage Nov 05 '20 at 08:10
10

Simulator 11.4: This issue has been fixed

You need to reset the default isActive value in the second view. It works on devices and emulators.

struct NavigationViewDemo: View {
    @State var isActive = false

    var body: some View {
        NavigationView {
            VStack {
                Text("View1")
                NavigationLink(
                    destination: NavigationViewDemo_View2(isActive: $isActive),
                    isActive: $isActive,
                    label: { Button(action: { self.isActive = true }, label: { Text("click") }) })
            }
        }
    }
}

struct NavigationViewDemo_View2: View {
    @Binding var isActive: Bool

    var body: some View {
        Text("View2")
            .navigationBarItems(leading: Button(action: { self.isActive = false }, label: { Text("Back") }))
    }
}
Victor Kushnerov
  • 3,706
  • 27
  • 56
  • I'm having issues with both the simulator and my physical device on getting NavigationLink working more than once. Nothing fixes it in the simulator, but a similar method to this that works for my physical device is setting an onDisappear on the View2 which resets the active flag. It's a marginally cleaner workaround for an Xcode bug (because you don't have to bind to a state that View2 shouldn't know about). NavigationViewDemo_View2().onDisappear(perform: { self.isActive = false }) – SJoshi Feb 13 '20 at 01:46
  • @SJoshi I got it but `onDisappear ` will be called after `isActive` is false so NavigationView won't work properly. It's temporary solution for emulators only because NavigationView works correctly on devices. In previous versions of emulators NavigationView worked I hope it will be fixed in future emulator. – Victor Kushnerov Feb 13 '20 at 05:30
  • Strangely, this code doesn't work on my simulator OR physical device - the solution I proposed resets the active flag when the detail view is dismissed, and allows the physical device to work. Word on the street is that Xcode 13.4 fixes this issue – SJoshi Feb 14 '20 at 00:00
  • I tested on simulator 11.3.1 it works like a charm. You see 3 starts I suppose others helped too. – Victor Kushnerov Feb 14 '20 at 06:25
  • Yep, me too, tested on that - using multiple iPhones. Also, tested on 4 physical devices - no luck. This bug is definitely a ridiculous one. I ended up doing some ridiculous workaround in the meantime for the simulator. – SJoshi Feb 14 '20 at 07:56
  • Isn't working, when Button taken under navigationBarItems. – Nikunj Rajyaguru Feb 20 '20 at 11:10
3

Presumably this will be resolved when Apple fixes the related bug that prevents 13.3 from being selectable as a deployment target.

I'm experiencing the same issue as everyone else. This issue is present in simulator and preview running 13.2, but is fixed when deploying to my own device running 13.3.

Brandon C.
  • 410
  • 4
  • 8
1

As @Александр Грабовский said its seems like a Xcode 11.3 bug, I am encountering the same problem, you must downgrade or use some workaround like custom back button as below

struct ContentView: View {
    @State private var pushed: Bool = false

    var body: some View {

        NavigationView {
            VStack {
                Button("Show Detail View") {
                    self.pushed.toggle()
                }

                NavigationLink(destination: Test(pushed: $pushed), isActive: $pushed) { EmptyView() }
            }.navigationBarTitle("title1")
        }
    }
}
struct Test: View {
    @Binding var pushed: Bool
    var body: some View {
        Text("Hello, World!")
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: BackButton(label: "Back") {
                self.pushed = false
            })
    }
}
struct BackButton: View {
    let label: String
    let closure: () -> ()

    var body: some View {
        Button(action: { self.closure() }) {
            HStack {
                Image(systemName: "chevron.left")
                Text(label)
            }
        }
    }
}
ozmpai
  • 2,454
  • 2
  • 14
  • 19
1

For anyone who's having the same symptom with other versions of iOS than the buggy beta identified by other answers, there's another reason you might be seeing this behaviour.

If your NavigationLink is nested inside another NavigationLink, the inner NavigationLink will only work once, unless you add isDetailLink(false) to the outer link.

stevex
  • 5,589
  • 37
  • 52