NavigationBackport icon indicating copy to clipboard operation
NavigationBackport copied to clipboard

Runtime issue relating to NavigationLink usage

Open JosephDuffy opened this issue 2 years ago • 5 comments

I'm not sure if it's possible to fix this, but at runtime I get the following issue:

NavigationLink presenting a value must appear inside a NavigationContent-based NavigationView. Link will be disabled.

I'm not 100% confident of the root cause of this, but I know it happens when I tap an NBNavigationLink.

I see 2 places in the project that use NavigationLink: https://github.com/johnpatrickmorgan/NavigationBackport/blob/79fed7bfd6323850634881632365c7f4318442f0/Sources/NavigationBackport/Router.swift#L36 and https://github.com/johnpatrickmorgan/NavigationBackport/blob/79fed7bfd6323850634881632365c7f4318442f0/Sources/NavigationBackport/Node.swift#L38. I tried – naively – to wrap these in NavigationViews, but I guess the NavigationView then handles/overrides the links being tapping the link then does nothing.

Maybe this is something we'll just have to live with, but it would be nice to not have the runtime issue if possible!

I'm using Xcode 14 beta 2.

JosephDuffy avatar Jul 01 '22 22:07 JosephDuffy

Thanks @JosephDuffy. My guess is that these are erroneous warnings: the text refers to NavigationLink presenting a value, but the only NavigationLinks used, as you found, are not using the value-based initialisers. I also saw a couple of others saw these warnings inexplicably, but I wasn't able to make a small reproduction.

johnpatrickmorgan avatar Jul 02 '22 21:07 johnpatrickmorgan

Sounds like a beta bug then, hopefully it gets resolved in an Xcode update 😊

I'm happy for this to be closed, or kept open for visibility, it's up to you!

JosephDuffy avatar Jul 06 '22 02:07 JosephDuffy

Thanks, I'll leave it open for visibility and hope it gets resolved.

johnpatrickmorgan avatar Jul 09 '22 22:07 johnpatrickmorgan

I get the same message when I tap the back button but nothing is broken

advancedtw avatar Sep 19 '22 08:09 advancedtw

Thanks, I still think this is an erroneous message. I can trigger it with the following vanilla SwiftUI code:


import SwiftUI

@main
struct NavigationWarningLogDemoApp: App {
  var body: some Scene {
    WindowGroup {
      NavigationView {
        Content1View()
      }.navigationViewStyle(.stack)
    }
  }
}

struct Content1View: View {
  @State var pushing = false
  
  var body: some View {
    VStack {
      NavigationLink(destination: Content2View(popToRoot: { pushing = false }), isActive: $pushing, label: { Text("Go")})
    }
    .navigationTitle("1")
  }
}

struct Content2View: View {
  @State var pushing = false
  let popToRoot: () -> Void
  var body: some View {
    VStack {
      NavigationLink(destination: Content3View(popToRoot: popToRoot), isActive: $pushing, label: { Text("Go")})
      Button(action: popToRoot, label: { Text("Pop to root")})
    }
    .navigationTitle("2")
  }
}

struct Content3View: View {
  @State var pushing = false
  let popToRoot: () -> Void
  
  var body: some View {
    VStack {
      // The warning does not appear if you remove this NavigationLink.
      NavigationLink(destination: Text("4"), isActive: $pushing, label: { Text("Go")})
      // Tapping this button triggers a warning to be logged:
      //
      // NavigationLink presenting a value must appear inside a NavigationContent-based NavigationView. Link will be disabled.
      Button(action: popToRoot, label: { Text("Pop to root")})
    }
    .navigationTitle("3")
  }
}

I’ve filed a feedback FB11490806.

johnpatrickmorgan avatar Sep 19 '22 09:09 johnpatrickmorgan

Still experiencing this issue. Any ways to solve it?

ivarvanwooning avatar Apr 03 '23 19:04 ivarvanwooning

@ivarvanwooning I'm afraid not. As this affects vanilla SwiftUI (whenever a NavigationLink is removed from the view tree due to popping multiple screens), I can't do much beyond filing a feedback (FB11490806).

johnpatrickmorgan avatar Apr 03 '23 20:04 johnpatrickmorgan

@johnpatrickmorgan Ah, that's really too bad. The library works amazing, but it fills my console with warnings. Hopefully we can somehow find a workaround or way to mute it in the future.

ivarvanwooning avatar Apr 03 '23 22:04 ivarvanwooning

Apple replied:

The NavigationView API and the NavigationLink(destination:isActive:label:)' method was deprecated in iOS 16.0: I would recommend you use NavigationLink(value:label:) inside a NavigationStack or NavigationSplitView. It’s important you consider migrating to new navigation types.

The compiler warnings are a good indicator of potential issues in your project. Disabling the compiler warnings is typically not the recommended approach. Additionally, I would suggest you migrate to the New Navigation type and use a conditional compilation so you're able to support iOS less than 16.0.

Apart from this, there is no workaround DTS can provide for Feedback ID FB12111423; it is still under investigation. Please continue to track the problem via the bug report.

Not very helpful.

ivarvanwooning avatar Apr 13 '23 21:04 ivarvanwooning

In the latest release (v0.8.0), you can add .nbUseNavigationStack(.whenAvailable) anywhere outside your NBNavigationStack so that the library will use NavigationStack under the hood instead of NavigationView, which avoids these annoying logs.

johnpatrickmorgan avatar May 06 '23 22:05 johnpatrickmorgan