NavigationDestination triggered from alert

208 views Asked by At

I'm trying to launch a new view when the "Host" button on the alert is pressed, but I'm having difficulty determining where to place the NavigationDestination in the new iOS 16. Here is my current code. I want the user to be able to press "Host Game" and then be prompted to enter their name before loading the "Lobby View."

struct HomeView: View {
    @State private var playerName: String = ""
    @State private var isGameHosted: Bool = false
    @State private var currentGame: Game?
    @State private var showingNameAlert: Bool = false
    @State private var gameID: String?

    var body: some View {
        NavigationStack {
            VStack(spacing: 20) {
                Text("Game")
                    .bold()
                    .font(Font.custom("Futura", size: 60))
                    .foregroundColor(.red)

                Button(action: {
                    self.showingNameAlert = true
                }) {
                    RoundedRectangle(cornerRadius: 8)
                        .frame(width: 300, height: 50)
                        .foregroundColor(.red)
                        .overlay(
                            Text("Host Game")
                                .foregroundColor(.white)
                                .font(Font.custom("Futura", size: 20))
                                .bold()
                        )
                }
                .navigationDestination(isPresented: $isGameHosted) {
                    LobbyView(game: currentGame!)
                }

                Button(action: {
                    print("Join Game Tapped")
                }) {
                    RoundedRectangle(cornerRadius: 8)
                        .frame(width: 300, height: 50)
                        .foregroundColor(.red)
                        .overlay(
                            Text("Join Game")
                                .foregroundColor(.white)
                                .font(Font.custom("Futura", size: 20))
                                .bold()
                        )
                }

                Spacer()
            }
        }
        .alert("Enter Your Name", isPresented: $showingNameAlert) {
            TextField("Name", text: $playerName)
                .textInputAutocapitalization(.words)
            Button("Host", action: {
                if self.playerName != "" {
                    self.hostGame()
                    self.showingNameAlert = false
                    self.isGameHosted = true
                }
            })
            Button("Cancel", role: .cancel) { }
        } message: {
            Text("Please enter your name to host the game.")
        }
    }
1

There are 1 answers

0
Benzy Neez On

If I understand correctly, the question is about where to put the navigationDestination.

The documentation is not very specific, although it does identify some special cases:

Add this view modifer to a view inside a NavigationStack

Do not put a navigation destination modifier inside a “lazy” container, like List or LazyVStack. These containers create child views only when needed to render on screen. Add the navigation destination modifier outside these containers so that the navigation stack can always see the destination.

As a general rule, I would suggest adding it to the parent container. So in your case, I would probably put it on the VStack rather than on a Button. But it's not wrong to have it on a Button here, since the parent container does not use lazy loading.