How to use NavigationStack in SwiftUI

In this tutorial, you'll learn to build a navigation sequence in iOS using SwiftUI

Share:

Mar 1, 2023 651 Words

Read Time: 4 Minutes

A screenshot of code-snippet to use NavigationStack in SwiftUI in iOS

Introduction

Most iOS features use and depend on the navigation functionality.

With iOS 16, SwiftUI provides the NavigationStack1 which helps us use this brilliant functionality in just a few lines of swift code.

In this tutorial, I’ll teach you to build your first NavigationStack and leverage data passing between navigation screens in iOS using SwiftUI

A basic example with NavigationLink

We will create a clickable text inside a NavigationLink2 view.

When clicked or pressed, the app should take us to the next view and show some text.

There are several ways to use NavigationLink but we shall focus on a simple example to get a grasp on how it works.

💡 NavigationLink takes a parameter called destination which expects the View that needs to be rendered after clicking the enclosing link.

Here is a sample snippet.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            NavigationLink(
                "Click This",
                destination: Text("You clicked")
            )
        }
    }
}

Let’s give this NavigationLink a title using navigationtitle3 modifier


import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            NavigationLink(
                "Click This",
                destination: Text("You clicked")
            )
            .navigationTitle("Welcome")
        }
    }
}

This is the simplest usage of NavigationStack.

A more useful example with NavigationLink

We’ve defined a text based link and a simple text view in the destination.

  1. Click Text — “Click This”
  2. Navigate to new view with Text — “You Clicked”

What if we want to change this a bit?

  1. Click Image
  2. Navigate to a new view with Text

To implement this requirement, we shall change the way we use NavigationLink

💡 We shall keep the destination parameter as it is, we shall move the Label part inside the defintion.

import SwiftUI

struct ContentView: View {
    var body: some View {
            NavigationStack {
                NavigationLink(
                    destination: Text("You clicked")
                ){
                    Image(systemName: "arrow.up.right")
                        .resizable()
                        .frame(width: 50.0, height: 50.0)
                }
                .navigationTitle("Welcome")
            }
        }
}

Now, let’s change the destination view as well. We shall attempt to change it to an Image View.

import SwiftUI

struct ContentView: View {
    var body: some View {
            NavigationStack {
                NavigationLink(
                    destination:  Image(systemName: "arrow.up.right")
                        .resizable()
                        .frame(width: 50.0, height: 50.0)
                ){
                    Image(systemName: "arrow.up.right")
                        .resizable()
                        .frame(width: 50.0, height: 50.0)
                }
                .navigationTitle("Welcome")
            }
        }
}

Let’s clean this up a bit. Let’s re-use variables to make this robust and clean.

import SwiftUI

struct ContentView: View {
    
    @State private var image: Image =
        Image(systemName: "arrow.up.right")
        .resizable()

    var body: some View {
        NavigationStack {
            NavigationLink(
                destination:  image.frame(width: 50.0, height: 50.0)
            ){
                image.frame(width: 50.0, height: 50.0)
            }
            .navigationTitle("Welcome")
        }
    }
}

Now, what if the destination view consisted of multiple views ( in a VStack for instance) ?

We can define a separate destination view and pass it in the destination parameter.

import SwiftUI

struct CustomView: View {
    
    var body: some View {
        VStack {
            Text("You'd Clicked")
        }
        .navigationTitle("Second View")
    }
}

struct ContentView: View {
    
    @State private var image: Image =
        Image(systemName: "arrow.up.right")
        .resizable()

    var body: some View {
        NavigationStack {
            NavigationLink(
                destination: CustomView()
            ){
                image.frame(width: 50.0, height: 50.0)
            }
            .navigationTitle("Welcome")
        }
    }
}

Data passing using binding4 variable

We can pass data to the destination view as a constructor argument.

import SwiftUI

struct CustomView: View {
    
    @Binding var img: Image
    
    var body: some View {
        VStack {
            Spacer()
            Text("You Clicked")
            Spacer()
            img.frame(width: 50.0, height: 50.0)
            Spacer()
        }
        .navigationTitle("Welcome 2")
    }
}

struct ContentView: View {
    
    @State private var image: Image =
        Image(systemName: "arrow.up.right")
        .resizable()

    var body: some View {
        NavigationStack {
            NavigationLink(
                destination: CustomView(img: $image)
            ){
                image.frame(width: 50.0, height: 50.0)
            }
            .navigationTitle("Welcome")
        }
    }
}

In this tutorial, you’ve learnt how to built a simple and interactive navigation sequence in iOS with a few lines of Swift.

This knowledge can be used to build your first iOS app.

😃📱 Build something and share it with the world.

👋 – @TnvMadhav

References

Find more posts from following topics

accurate-requests
api-development
api-testing
api-testing-tools
array
automated-testing
bad-habits
base64-decoder
base64-encoder
binding
blog
blogging
bulma-css
bulma.io
button-swiftui
chatgpt
clipboard
code
code-block
code-snippet
comparison
compile
configuring-debugger-for-django-in-vs-code
configuring-launch.json-for-python-debugger
copy
copy-to-clipboard
copy-to-clipboard-neovim
css
current-date
current-time
current-timestamp
debugger-setup-in-visual-studio-code
debugging-django-app-in-visual-studio-code
debugging-python-code-in-visual-studio-code
debugging-python-programs-with-visual-studio-code
debugging-python-with-virtual-environment-in-vs-code
developer-productivity
developers
development-workflow
dom
dynamic-sitemap-in-nextjs
engineering-dashboard
flowcharts
git
git-diff
github
global-keyboard-shorcut
global-shortcut
go
go-hugo
go-programming
go-to-line
golang
golang-development
good-habits
gorilla-websocket
gpt
gpt-3.5
gpt-4
gpt-4-api
guide
gumroad
habits
habits-tracker-notion-template
hamburger-menu
hotkeys
html
hugo
ide
image
image-sharing
image-tool-for-ios
imagerenderer
include-timestamp
integrated-development-environment
ios
ios-16
ios16
javascript
keyboard-shortcut
linux
macos
map
markdown
markdown-code
mental-programming
menu
menubarextra
mermaid-syntax
mistake-tracker-notion
mobile-view
modifier
navbar
navigationlink
navigationstack
neovim
next.js
nextjs
nextjs-markdown
nextjs-sitemap
nextjs-sitemaps
nice-shot
nice-shot-pro
notion
notion-api
notion-api-python
notion-budget
notion-budget-template
notion-budget-tracker
notion-bug-report-tracker
notion-dashboard
notion-expense-manager
notion-habits
notion-habits-dashboard
notion-habits-template
notion-habits-tracker
notion-habits-tracker-template
notion-issue-tracker
notion-mistake-tracker
notion-product
notion-product-dashboard
notion-product-roadmap
notion-product-roadmap-dashboard
notion-tasks
notion-tasks-dashboard
notion-tasks-template
notion-tasks-tracker
notion-template
notionworkspaces
openai
osx
personal-ifttt-framework
photospicker
photospickeritem
phpickerfilter
postman-capabilities
postman-request
pre-request-script
product-roadmap-notion-template
product-roadmap-template
productivity
programming
python
python-api
python-debugger-tutorial-for-vs-code
python-debugging-mode-in-vs-code
python-notion-api
real-time-communication
rehype
remark
request-data
running-debugger-in-visual-studio-code
running-django-app-in-debugging-mode
running-program-in-debugging-mode-in-vs-code
running-python-code-in-debugging-mode
screenshot-app-for-ios
screenshot-app-ios
screenshot-ios
screenshot-tool-for-ios
set-current-timestamp
setting-up-debugger-in-vs-code-for-python
share-extension
sharelink
sharepreview
sharesheet
simple-websocket-server
sitemap
slice
slider
step-by-step-guide
stocks-profits-tracker
stocks-profits-tracker-template
stocks-tracker
struct
sustained-vigilance
swift
swiftui
swiftui-button
swiftui-button-action
swiftui-button-style
table-of-contents
tasks-tracker-notion-template
textfield-swiftui
timeliness
timestamp-integration
transferable
triggers-and-actions
tutorial
us-stocks
usa-stocks
useful-ios-features
using-breakpoints-in-python-debugger
using-virtual-environment-with-python-debugger
vanilla-javascript
variable
vim
visual-mode
visual-studio-code
vs-code
vscode
vscode-go-to-line
web-sockets-in-go
websocket-client
websocket-programming
websocket-server
xcode