Swiftui: Navigationlink Not Working If Not in a List

NavigationLink in SwiftUI not working anymore

I can see from the comments that you've found out it will only work in a NavigationView and are now wondering why. It only matters that your view is embedded in a NavigationView directly above it the View hierarchy. For example, this code would work:

struct FirstView: View {
var body: some View {
NavigationView {
NavigationLink(label: "Go to next view", destination: NextView())
}
}
}

struct NextView: View {
...

While this won't:

struct FirstView: View {
@State var modalPresented = false
var body: some View {
NavigationView {
Button("Show fullscreen cover"){
modalPresented = true
}
}
.fullScreenCover(isPresented: $modalPresented, content: SecondView())
}
}

struct SecondView: View {
var body: some View {
NavigationLink(label: "Go to next view", destination: NextView())
// Doesn't work because the view is in a fullScreenCover and therefore not a part of the NavigationView.
}
}

SwiftUI NavigationLink for iOS 14.5 not working

I got exactly the same problem, everything works fine with Xcode 12.4.

https://developer.apple.com/forums/thread/677333

I try to following this thread, it might work but on some case, I still have this bug.

       NavigationLink(destination: EmptyView()) {
EmptyView()
}

Apparently, you can put this 3 lines of code close to your NavigationLink...
If someone got a better answer I will really appreciate it !

NavigationLink is not working in fullScreenCover when I click item in list

The .sheet and .fullScreenCover introduce new presentations, so we need new NavigationView inside

Button("New Message"){
shownFCover.toggle()
}.fullScreenCover(isPresented: $shownFCover) {
VStack {
Button("Close"){
shownFCover.toggle()
}
NavigationView { // << here !!
List {
ForEach(0..<16) { index in
NavigationLink {
Text("Hello")
} label: {
HStack{
Image(systemName: "\(index).circle.fill").font(.title).foregroundColor(.red)

Text("\(index). Item")
}
}

}
}
}
}
}

*Note: I recommend to separate full screen content into standalone view instead of having all right there.

So it would look like

Button("New Message"){
shownFCover.toggle()
}.fullScreenCover(isPresented: $shownFCover) {
FCoverView(shownCover: $shownFCover)
}

Unable to activate NavigationLink programmatically, in a List ForEach

The issue is you need a Binding<Bool> -- not just a simple boolean condition. Adding $ gives you a binding to the displayedGame (ie an Binding<Int?>), but not a Binding<Bool>, which is what the NavigationLink expects.

One solution is to create a custom Binding for the condition you're looking for:

class GamesViewModel: ObservableObject /*, WebSocketDelegate */ {
@Published var currentGames: [Int] = [2, 3]
@Published var displayedGame: Int?

func navigationBindingForGame(gameNumber: Int) -> Binding<Bool> {
.init {
self.displayedGame == gameNumber
} set: { newValue in
self.displayedGame = newValue ? gameNumber : nil
}
}

func updateCurrentGames() {
currentGames = currentGames.count == 3 ? [1, 2, 3, 4] : [2, 5, 7]
}

func updateDisplayedGame() {
displayedGame = currentGames.randomElement() ?? 0
}
}

struct ContentView: View {
@StateObject private var vm:GamesViewModel = GamesViewModel()

var body: some View {
NavigationView {
VStack {
NavigationLink(isActive: vm.navigationBindingForGame(gameNumber: vm.displayedGame ?? -1)) {
GameView(gameNumber: vm.displayedGame ?? 0)
} label: {
EmptyView()
}
List {
ForEach(vm.currentGames, id: \.self) { gameNumber in
NavigationLink(destination: GameView(gameNumber: gameNumber),
isActive: vm.navigationBindingForGame(gameNumber: gameNumber)
) {
Text("Game #\(gameNumber)")
}
}
}
Button(
action: { vm.updateCurrentGames() },
label: { Text("Update games") }
).padding(4)

Button(
action: { vm.updateDisplayedGame() },
label: { Text("Join a random game") }
).padding(4)

}.navigationBarTitle("Select a game")
}
}
}

I changed displayedGame to an Int? because I think semantically it makes a little more sense to be an Optional rather than set to 0 if there's no displayed game, but that could easily be changed back if need be.



Related Topics



Leave a reply



Submit