Home > other >  NavigationLink destination immediately disappear after loading
NavigationLink destination immediately disappear after loading

Time:09-30

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:

screencast

CodePudding user response:

The Category id is not stable, so the 3 categories are given new ids every time the View2 is init, 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.

  • Related