Reputation: 983
I'm quite new to Swift and I'm struggling with this implementation. I moved my code to playground so it's easier for you to debug if you copy/paste on your Xcode.
Basically once loading View3 the view immediately disappear and you are pushed back to View2.
I identify the issue to be with the categories array on the View2. If I separate the 3 categories in 3 NavigationLink (instead of looping) the code works just fine.
I just don't understand why this doesn't work and I'd love if you help me find out what's wrong with this implementation?
import UIKit
import Foundation
import SwiftUI
import PlaygroundSupport
struct Article: Identifiable {
var id = UUID()
var title : String
}
struct Category: Identifiable {
var id = UUID()
var name : String
}
class DataManager: ObservableObject{
@Published var articles : [Article] = []
func getArticles(){
let article = Article(title: "Just a test")
if !articles.contains(where: {$0.title == article.title}) {
articles.append(article)
}
}
func clearArticles(){
articles.removeAll()
}
}
struct View1: View{
@StateObject var dataManager = DataManager()
var body: some View {
NavigationView{
List(){
NavigationLink(destination: View2(), label: { Text("View 2") })
}
.navigationBarTitle("View 1")
.listStyle(.insetGrouped)
}
.navigationViewStyle(StackNavigationViewStyle())
.environmentObject(dataManager)
}
}
struct View2: View{
let categories = [
Category(name: "Category 1"),
Category(name: "Category 2"),
Category(name: "Category 3")
]
var body: some View {
List(categories){ category in
NavigationLink(destination: View3(category: category), label: { Text(category.name) })
}
.navigationBarTitle("View 2")
.navigationBarTitleDisplayMode(.inline)
}
}
struct View3: View{
@EnvironmentObject var dataManager: DataManager
let category: Category
var body: some View {
List(dataManager.articles) { article in
HStack {
Text(article.title)
}
}.task{
dataManager.getArticles()
}.onDisappear(){
dataManager.clearArticles()
}
.navigationTitle("View 3")
.navigationBarTitleDisplayMode(.inline)
}
}
PlaygroundPage.current.setLiveView(View1())
This is the resulting behaviour:
Upvotes: 1
Views: 434
Reputation: 30569
The Category id is not stable so every time the View2 is init, a new array with different ids is created so the ForEach
is creating new NavigationLinks which are not active so the previously active one is gone and it reacts by popping it off the nav stack, try this:
struct Category: Identifiable {
var id: String {
name
}
var name : String
}
But it would be better if you put them in the data store object so you aren't creating them every time View2 is init.
Upvotes: 1