Reader small image

You're reading from  SwiftUI Essentials – iOS 14 Edition

Product typeBook
Published inMay 2021
Reading LevelBeginner
PublisherPackt
ISBN-139781801813228
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Neil Smyth
Neil Smyth
author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor’s degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth

Right arrow

29. A SwiftUI List and Navigation Tutorial

The previous chapter introduced the List, NavigationView and NavigationLink views and explained how these can be used to present a navigable and editable list of items to the user. This chapter will work through the creation of a project intended to provide a practical example of these concepts.

29.1 About the ListNavDemo Project

When completed, the project will consist of a List view in which each row contains a cell displaying image and text information. Selecting a row within the list will navigate to a details screen containing more information about the selected item. In addition, the List view will include options to add and remove entries and to change the ordering of rows in the list.

The project will also make extensive use of state properties and observable objects to keep the user interface synchronized with the data model.

29.2 Creating the ListNavDemo Project

Launch Xcode and select the option to create a new Multiplatform App named ListNavDemo.

29.3 Preparing the Project

Before beginning development of the app project, some preparatory work needs to be performed involving the addition of image and data assets which will be needed later in the chapter.

The assets to be used in the project are included in the source code sample download provided with the book available from the following URL:

https://www.ebookfrenzy.com/retail/swiftui-ios14/

Once the code samples have been downloaded and unpacked, open a Finder window, locate the CarAssets.xcassets folder and drag and drop it into the Shared folder within the project navigator panel as illustrated in Figure 29-1:

Figure 29-1

When the options dialog appears, enable the Copy items if needed option so that the assets are included within the project folder before clicking on the Finish button. With the image assets added, find the carData.json file located in the CarData folder and drag and drop it onto the Shared folder in the Project navigator panel to also...

29.4 Adding the Car Structure

Now that the JSON file has been added to the project, a structure needs to be declared to represent each car model. Add a new Swift file to the project by selecting the File -> New -> File… menu option, selecting Swift File in the template dialog and clicking on the Next button. On the subsequent screen, name the file Car.swift before clicking on the Create button.

Once created, the new file will load into the code editor where it needs to be modified so that it reads as follows:

import SwiftUI

 

struct Car : Codable, Identifiable {

    var id: String

    var name: String

    

    var description: String

    var isHybrid: Bool

    

    var imageName: String

}

As we can see, the structure contains a property for each field in the JSON file and is declared as...

29.5 Loading the JSON Data

The project is also going to need a way to load the carData.json file and translate the car entries into an array of Car objects. For this we will add another Swift file containing a convenience function that reads the JSON file and initializes an array which can be accessed elsewhere in the project.

Using the steps outlined previously, add another Swift file named CarData.swift to the project and modify it as follows:

import UIKit

import SwiftUI

 

var carData: [Car] = loadJson("carData.json")

 

func loadJson<T: Decodable>(_ filename: String) -> T {

    let data: Data

    

    guard let file = Bundle.main.url(forResource: filename,

                                  withExtension...

29.6 Adding the Data Store

When the user interface has been designed, the List view will rely on an observable object to ensure that the latest data is always displayed to the user. So far, we have a Car structure and an array of Car objects loaded from the JSON file to act as a data source for the project. The last step in getting the data ready for use in the app is to add a data store structure. This structure will need to contain a published property which can be observed by the user interface to keep the List view up to date. Add another Swift file to the project, this time named CarStore.swift, and implement the class as follows:

import SwiftUI

import Combine

 

class CarStore : ObservableObject {

    

    @Published var cars: [Car]

    

    init (cars: [Car] = []) {

        self.cars = cars

    }

}

...

29.7 Designing the Content View

Select the ContentView.swift file and modify it as follows to add a state object binding to an instance of CarStore, passing through to its initializer the carData array created in the CarData.swift file:

import SwiftUI

 

struct ContentView: View {

    

    @StateObject var carStore : CarStore = CarStore(cars: carData)

.

.

The content view is going to require a List view to display information about each car. Now that we have access to the array of cars via the carStore property, we can use a ForEach loop to display a row for each car model. The cell for each row will be implemented as an HStack containing an Image and a Text view, the content of which will be extracted from the carData array elements. Remaining in the ContentView.swift file, delete the existing “Hello, world” Text view and implement the list as follows:

.

.

var body: some View {

  ...

29.8 Designing the Detail View

When a user taps a row in the list, a detail screen will appear showing additional information about the selected car. The layout for this screen will be declared in a separate SwiftUI View file which now needs to be added to the project. Use the File -> New -> File… menu option once again, this time selecting the SwiftUI View template option and naming the file CarDetail.

When the user navigates to this view from within the List, it will need to be passed the Car instance for the selected car so that the correct details are displayed. Begin by adding a property to the structure and configuring the preview provider to display the details of the first car in the carData array within the preview canvas as follows:

import SwiftUI

 

struct CarDetail: View {

    

    let selectedCar: Car

    

    var body: some View {

   ...

29.9 Adding Navigation to the List

The next step in this tutorial is to return to the List view in the ContentView.swift file and implement navigation so that selecting a row displays the detail screen populated with the corresponding car details.

With the ContentView.swift file loaded into the code editor, locate the ListCell subview declaration and embed the HStack in a NavigationLink with the CarDetail view configured as the destination, making sure to pass through the selected car object:

struct ListCell: View {

    

    var car: Car

    

    var body: some View {

        

        NavigationLink(destination: CarDetail(selectedCar: car)) {

            HStack {

            ...

29.10 Designing the Add Car View

The final view to be added to the project represents the screen to be displayed when the user is adding a new car to the list. Add a new SwiftUI View file to the project named AddNewCar.swift including some state properties and a declaration for storing a reference to the carStore binding (this reference will be passed to the view from the ContentView when the user taps an Add button). Also modify the preview provider to pass the carData array into the view for testing purposes:

import SwiftUI

 

struct AddNewCar: View {

    

    @StateObject var carStore : CarStore

    @State private var isHybrid = false

    @State private var name: String = ""

    @State private var description: String = ""

.

.

struct AddNewCar_Previews: PreviewProvider {

    static var previews: some...

29.11 Implementing Add and Edit Buttons

The Add and Edit buttons will be added to a navigation bar applied to the List view in the ContentView layout. The Navigation bar will also be used to display a title at the top of the list. These changes require the use of the navigationBarTitle() and navigationBarItems() modifiers as follows:

var body: some View {

    

    NavigationView {

            List {

                ForEach (carStore.cars) { car in

                    ListCell(car: car)

            }

        }

        .navigationBarTitle(Text(...

29.12 Adding the Edit Button Methods

The final task in this tutorial is to add some action methods to be used by the EditButton view added to the navigation bar in the previous section. Because these actions are to be available for every row in the list, the actions must be applied to the list cells as follows:

var body: some View {

    

    NavigationView {

            List {

                ForEach (carStore.cars) { car in

                    ListCell(car: car)

            }

            .onDelete(perform: deleteItems)

       ...

29.13 Summary

The main objective of this chapter has been to provide a practical example of using lists, navigation views and navigation links within a SwiftUI project. This included the implementation of dynamic lists and list editing features. The chapter also served to reinforce topics covered in previous chapters including the use of observable objects, state properties and property bindings. The chapter also introduced some additional SwiftUI features including the Form container view, navigation bar items and the TextField view.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
SwiftUI Essentials – iOS 14 Edition
Published in: May 2021Publisher: PacktISBN-13: 9781801813228
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £13.99/month. Cancel anytime

Author (1)

author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor’s degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth