charmingcompanions.com

Mastering NavigationView in SwiftUI: A Comprehensive Guide

Written on

Chapter 1: Introduction to NavigationView

In SwiftUI, the NavigationView component facilitates a structured method for transitioning between views, including the ability to return to previously viewed screens. This feature is essential for applications with multiple screens that showcase various functionalities. This tutorial is part of my ongoing series on SwiftUI.

To begin, either create a new project or open an existing one for practice. The following guide provides a detailed walkthrough on setting up a new project.

How Does NavigationView Work?

The syntax for implementing a NavigationView is as follows:

NavigationView {

NavigationLink(destination: //Next view) {

//Label for user interaction

}

//Link appearance

}

Let's illustrate this with a straightforward example by filling in the comments in the syntax:

struct ContentView: View {

var body: some View {

NavigationView {

NavigationLink(destination: Text("This is the second view")) {

Text("Go to second view")

}

}

} //body

} //ContentView

Once you run the code and select "Go to the second view," you will transition to a new screen displaying "This is the second view."

Basic NavigationView example

In a practical application, it's advisable to create a separate struct for the second view. By holding the Command key and clicking on Text, a list of options will pop up. Choose "Extract Subview."

Extract Subview

This will generate a subview in the form of a struct named ExtractedView. To adhere to best practices, rename it to SecondView.

Source code for Extracted SubView

Adding a Navigation Title

To enhance your app, let's set a title using the navigationTitle modifier:

NavigationView {

NavigationLink(destination: SecondView()) {

Text("Go to second view")

}

.navigationTitle("SwiftUI Navigation")

}

Adding navigationTitle

By default, the navigation bar will display a large title that shrinks as you scroll up. To maintain a compact navigation bar, use the .inline modifier like this:

NavigationLink(destination: SecondView()) {

Text("Go to second view")

}

.navigationTitle("SwiftUI Navigation")

.navigationBarTitleDisplayMode(.inline)

Making the navigation title compact

Customizing Navigation Bar Appearance

As of now, SwiftUI lacks direct modifiers for adjusting the navigation bar's font and color. Instead, you can utilize UINavigationBarAppearance from UIKit. For instance, to change the title color to blue and adjust the font style to Savoye LET, you can add the following code in ContentView:

init() {

let navBarAppearance = UINavigationBarAppearance()

navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.blue, .font: UIFont(name: "Savoye LET", size: 40)!]

navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.blue, .font: UIFont(name: "Savoye LET", size: 20)!]

UINavigationBar.appearance().standardAppearance = navBarAppearance

UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance

UINavigationBar.appearance().compactAppearance = navBarAppearance

} //init

Configuring font and color

In this code, we established a UINavigationBarAppearance constant named navBarAppearance, allowing us to configure attributes like largeTitleTextAttributes and titleTextAttributes. These configurations are then applied to standardAppearance, scrollEdgeAppearance, and compactAppearance.

The navigation bar will now appear as shown below based on the above settings:

Modifying navigation bar font and color

Changing the Back Button Color

The default color of the navigation view's back button is blue. You can alter this color using UINavigationBarAppearance. To change the back button's color to red, add the following line within init():

UINavigationBar.appearance().tintColor = .red

Changing back button to red

Utilizing NavigationView with a ForEach List

Now, let's implement NavigationView within a ForEach List, a crucial concept for many content-driven applications. If you're new to List and ForEach, it’s advisable to review a foundational tutorial before advancing.

We will create an application that navigates to the respective view upon tapping.

ForEach List with Navigation app

Before you begin, gather the images you wish to use. If you don't have any, you can download photos from Unsplash. Ensure all images are imported into the Assets directory. If you're unfamiliar with image handling in SwiftUI, consult this tutorial.

Once your assets are ready, create a new struct to hold the images and text:

struct Collections: Identifiable {

var id = UUID()

var name: String

var image: String

var content: String

}

Next, set up an array to store your data:

var collections = [

Collections(name: "Cafe", image: "rr-abrot", content: "Cafe. Lorem ipsum dolor sit amet."),

Collections(name: "Home", image: "ian-harber", content: "Home. Lorem ipsum dolor sit amet."),

Collections(name: "Commute", image: "charles-forerunner", content: "Commute. Lorem ipsum dolor sit amet."),

Collections(name: "Travel", image: "andrew-neel", content: "Travel. Lorem ipsum dolor sit amet."),

Collections(name: "Public", image: "clay-banks", content: "Public. Lorem ipsum dolor sit amet."),

Collections(name: "Office", image: "kate-sade", content: "Office. Lorem ipsum dolor sit amet."),

Collections(name: "Conference", image: "nastuh-abootalebi", content: "Conference. Lorem ipsum dolor sit amet.")

]

Make sure to update the image names in the array to match the files you will be using.

Next, design the appearance of the rows by creating a separate struct:

struct ImageLabelRow: View {

var collection: Collections

var body: some View {

ZStack(alignment: .trailing) {

Image(collection.image)

.resizable()

.aspectRatio(contentMode: .fill)

.frame(height: 150)

.cornerRadius(20)

.overlay(

Rectangle()

.foregroundColor(.black)

.cornerRadius(20)

.opacity(0.4)

)

Text(collection.name)

.font(.system(.largeTitle, design: .rounded))

.fontWeight(.black)

.foregroundColor(.white)

.padding()

}

}

}

When a link is tapped, it should navigate to another view. Let's create a simple version of this with the following code:

struct DetailView: View {

var collection: Collections

var body: some View {

Text(collection.content)

.font(.body)

}

}

Now that all external structs are prepared, let's implement the NavigationView within the ContentView's body:

NavigationView {

List(collections) { index in

ZStack {

ImageLabelRow(collection: index)

NavigationLink(destination: DetailView(collection: index)) {}

} //ZStack

} //List

.navigationTitle("Where are you?")

} //NavigationView

In this code, we created a NavigationView that contains a ForEach List to display all items from the collections variable. The ImageLabelRow struct is utilized for the list's design, paired with its corresponding Navigation Link leading to the DetailView.

ContentView final code Collections, ImageLabelRow, and DetailView final code

Run the application and test the links; they should redirect you to their respective contents.

For the complete source code, check out the GitHub repository.

In the next tutorial, we will explore the fundamentals of animation.

May your coding journey be successful,

  • Arc

The first video titled "The Complete Guide to NavigationView in SwiftUI" provides an in-depth look at using NavigationView effectively within your applications.

The second video, "SwiftUI Navigation - NavigationView & NavigationLink Tutorial," offers a comprehensive tutorial on implementing NavigationView and NavigationLink in SwiftUI.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Maximize Your Medium Reach: Strategies to Attract More Readers

Discover actionable strategies for writers on Medium to increase readership and engagement.

Exploring Earth in 2030: Three Compelling Futures

A look into three potential visions for Earth in 2030, shaped by today's choices and challenges.

Unlock the Secrets to Genius-Level Problem-Solving in 4 Steps

Explore four essential strategies for effective problem-solving and personal growth.