In this post, we will see how to use the new NavigationStack that has substituted the old NavigationView.
We start creating an iOS project and then, we add three Swift files called User, Core and UserType.
The first one is our Model, the second one is the Business layer and finally UserType is the UI:
[USER.SWIFT]
import Foundation
// The Hashable is a protocol that provides a hashValue to the object.
// The hashValue is used to compare two instances.
struct User: Identifiable, Hashable {
let id = UUID()
var name: String
var typeuser: TypeUser
}
enum TypeUser {
case A
case B
case C
var description: String {
switch self {
case .A: return "A"
case .B: return "B"
case .C: return "C"
}
}
}
[CORE.SWIFT]
import Foundation
class Core {
func GetAllUsers() -> [User] {
var result = [User]()
result.append(User(name: "John", typeuser: TypeUser.A))
result.append(User(name: "Neil", typeuser: TypeUser.B))
result.append(User(name: "Sally", typeuser: TypeUser.C))
return result
}
}
[USERTYPE.SWIFT]
import SwiftUI
struct UserType: View {
let name:String
let typeuser: TypeUser
var body: some View {
VStack{
HStack{
Text("Hello \(name)")
Text("Your type is \(typeuser.description)")
}
}
}
}
struct UserType_Previews: PreviewProvider {
static var previews: some View {
UserType(name: "TestName", typeuser: TypeUser.A)
}
}
Now, we modify the file ContentView to show a User list using NavigationStack:
[CONTENTVIEW.SWIFT]
import SwiftUI
struct ContentView: View {
let lstUser = Core().GetAllUsers()
var body: some View {
NavigationStack{
List(lstUser) { user in
NavigationLink("User: \(user.name)"){
UserType(name: user.name, typeuser: user.typeuser)
}
}
.navigationTitle("Users list")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
If we run the application, these will the results:
We can see that everything works fine but, nothing changed compare to the old NavigationView.
This is true but, in reality, there are some new features introduced with NavigationStack and, one of these, is the navigationDestination that allow us to create dynamic routes.
Let’s see an example.
We add other three views called UserTypeA, UserTypeB and UserTypeC:
[USERTYPEA.SWIFT]
import SwiftUI
struct UserTypeA: View {
let name:String
let typeuser: TypeUser
var body: some View {
ZStack {
// Definition background color
Color.yellow.edgesIgnoringSafeArea(.all)
VStack{
Text("Hello \(name)")
Text("Your type is \(typeuser.description)")
}
.bold()
.foregroundColor(.black)
.font(.system(size: 30))
}
}
}
struct UserTypeA_Previews: PreviewProvider {
static var previews: some View {
UserTypeA(name: "TestName", typeuser: TypeUser.A)
}
}
[USERTYPEB.SWIFT]
import SwiftUI
struct UserTypeB: View {
let name:String
let typeuser: TypeUser
var body: some View {
ZStack {
// Definition background color
Color.green.edgesIgnoringSafeArea(.all)
VStack{
Text("Hello \(name)")
Text("Your type is \(typeuser.description)")
}
.bold()
.foregroundColor(.black)
.font(.system(size: 30))
}
}
}
struct UserTypeB_Previews: PreviewProvider {
static var previews: some View {
UserTypeB(name: "TestName", typeuser: TypeUser.B)
}
}
[USERTYPEC.SWIFT]
import SwiftUI
struct UserTypeC: View {
let name:String
let typeuser: TypeUser
var body: some View {
ZStack {
// Definition background color
Color.orange.edgesIgnoringSafeArea(.all)
VStack{
Text("Hello \(name)")
Text("Your type is \(typeuser.description)")
}
.bold()
.foregroundColor(.black)
.font(.system(size: 30))
}
}
}
struct UserTypeC_Previews: PreviewProvider {
static var previews: some View {
UserTypeC(name: "TestName", typeuser: TypeUser.C)
}
}
Finally, we modify the ContentView in order to show one of these View above, based on the value of TypeUser:
[CONTENTVIEW.SWIFT]
import SwiftUI
struct ContentView: View {
let lstUser = Core().GetAllUsers()
var body: some View {
NavigationStack{
List(lstUser) { user in
NavigationLink(value: user){
Text("User: \(user.name)")
}
}
.navigationTitle("Users list")
// with navigationDEstination, we can choice the view to show
.navigationDestination(for: User.self){ user in
switch user.typeuser{
case TypeUser.A:
UserTypeA(name: user.name, typeuser: user.typeuser)
case TypeUser.B:
UserTypeB(name: user.name, typeuser: user.typeuser)
case TypeUser.C:
UserTypeC(name: user.name, typeuser: user.typeuser)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
We have done and now, if we run the application, these will be the results: