How to navigate to a new view from navigationBar button click in SwiftUI
Asked Answered
C

4

18

Learning to SwiftUI. Trying to navigate to a new view from navigation bar buttton clicked.
The sample code below:

var body: some View {
    NavigationView {
        List(0...< 5) { item in
            NavigationLink(destination: EventDetails()){
                EventView()
            }
        }
        .navigationBarTitle("Events")
            .navigationBarItems(trailing:
                NavigationLink(destination: CreateEvent()){
                    Text("Create Event")
                }
        )
    }
}
Centrepiece answered 14/7, 2019 at 2:59 Comment(5)
Are you trying to push CreateEvent onto the navigation stack or are you trying to present it modally?Dresser
Yes, pushing to the navigation stack.Centrepiece
Based on the code you provided, I do have a suggestion. It may be that this is just example code, but in this instance, CreateEvent should really be presented modally, not pushed onto the navigation stack. The reason is that if you have a list of events that each push a detail view onto the stack when pressed, creating a new event is really a secondary action unrelated to the navigation stack and should really be handled as a temporary view - like creating a new contact in the contacts app or a new calendar event in the calendar app.Dresser
DynamicNavigationDestinationLink seems to do the trick. When I present the view modally, it only works the first time I click the button. Subsequent click does nothing.Centrepiece
That is an issue with modal presentation currently and seems to just be a bug. I’m assuming it will be fixed before full release, but yes, at the moment that is a problem with presenting a view modally. If you managed to solve your problem, I’d suggest answering your own question and then accepting it so that people with a similar question can learn from what you’ve done to solve it.Dresser
R
9

Put the NavigationLink into the label of a button.

.navigationBarItems(
      trailing: Button(action: {}, label: {
         NavigationLink(destination: NewView()) {
              Text("")
         }
      }))
Rust answered 4/12, 2020 at 21:51 Comment(2)
navigationBarItems has been deprecatedGratuity
Works! It's strange though that the action - NavigationLink - has to be under label rather than action...Quiz
N
8

Three steps got this working for me : first add an @State Bool to track the showing of the new view :

@State var showNewView = false

Add the navigationBarItem, with an action that sets the above property :

 .navigationBarItems(trailing:
        Button(action: {
            self.showNewView = true
        }) {
            Text("Go To Destination")
        }
    )

Finally add a navigation link somewhere in your view code (this relies on also having a NavigationView somewhere in the view stack)

NavigationLink(
            destination: MyDestinationView(),
            isActive: $showNewView
        ) {
            EmptyView()
        }.isDetailLink(false)
Nonchalant answered 26/5, 2020 at 5:8 Comment(1)
Thanks it worked for me by removing .isDetailLink(false)Tributary
F
4

This works for me:

    .navigationBarItems(trailing: HStack { AddButton(destination: EntityAddView()) ; EditButton() } )

Where:

struct AddButton<Destination : View>: View {

    var destination:  Destination

    var body: some View {
        NavigationLink(destination: self.destination) { Image(systemName: "plus") }
    }
}
Followthrough answered 19/8, 2019 at 16:14 Comment(0)
D
2

It is an iOS13 bug at the moment: https://forums.developer.apple.com/thread/124757

The "sort-of" workaround can be found here: https://mcmap.net/q/238236/-how-to-show-navigationlink-as-a-button-in-swiftui

Here is my solution: MasterView -

import SwiftUI

struct MasterView: View {

    @State private var navigationSelectionTag: Int? = 0

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DestinationView(), tag: 1, selection: self.$navigationSelectionTag) {
                    EmptyView()
                }
                Spacer()
            }
            .navigationBarTitle("Master")
            .navigationBarItems(trailing: Button(action: {
                self.navigationSelectionTag = 1
            }, label: {
                Image(systemName: "person.fill")
            }))
        }
    }
}

struct MasterView_Previews: PreviewProvider {
    static var previews: some View {
        MasterView()
    }
}

And the DetailsView -

import SwiftUI

struct DetailsView: View {
    var body: some View {
        Text("Hello, Details!")
    }
}

struct DetailsView_Previews: PreviewProvider {
    static var previews: some View {
        DetailsView()
    }
}
Deity answered 3/12, 2019 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.