导航出现异常?

问题描述 投票:0回答:1

我是一名相当缺乏经验的 SwiftUI 程序员,所以我几乎总是对一件事或另一件事感到困惑。这次是导航。 我希望我的开始屏幕显示一个包含一些静态内容的列表,其中每行导航到一个动态列表,而我又想导航到一个视图以显示或编辑该行的内容。 在我的应用程序中,当我点击一行来显示/编辑它时,应用程序返回到开始视图。我不知何故弄乱了导航堆栈,或者做了其他错误 - 但什么?

我在一个小型演示应用程序中重新创建了该行为:

import SwiftUI
import SwiftUI

class InnerDataItem : Hashable, Identifiable, ObservableObject {
    var id = UUID()
    var innerInfo = ""
    
    init(innerInfo: String = "") {
        self.innerInfo = innerInfo
    }
    
    static func == (lhs: InnerDataItem, rhs: InnerDataItem) -> Bool {
        lhs.innerInfo == rhs.innerInfo
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(innerInfo)
    }
}

class DataModel : Identifiable, ObservableObject {
    let id: UUID = UUID()
    @Published var info = "My String array"
    @Published var innerData: [InnerDataItem] = []
    
    init(info: String = "My String array", innerData: [InnerDataItem]) {
        self.info = info
        self.innerData = innerData
    }
}

let testData = DataModel(
    info: "Data model object",
    innerData: [
        InnerDataItem(innerInfo: "(1) Inner info One"),
        InnerDataItem(innerInfo: "(1) Inner info Two"),
        InnerDataItem(innerInfo: "(1) Inner info Three"),
    ])

struct DataListView: View {
    @ObservedObject var data: DataModel
    @State var editMode: EditMode = .inactive
    
    var body: some View {
        NavigationStack {
            DataList(data: data)
                .environment(\.editMode, $editMode)
                .navigationDestination(for: InnerDataItem.self) { data in
                    DataEditItem(dataItem: data)
                }
        }
    }
}

struct DataList: View {
    @ObservedObject var data: DataModel
    
    var body: some View {
        List {
            ForEach(data.innerData) { item in
                NavigationLink(value: item) {
                    DataLine(dataItem: item)
                }
            }
        }
        
    }
}

struct DataLine: View {
    @ObservedObject var dataItem: InnerDataItem
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(dataItem.innerInfo).font(.largeTitle)
        }
    }
}

struct DataEditItem: View {
    @ObservedObject var dataItem: InnerDataItem
    
    var body: some View {
        Form {
            Section(header: Text("Visningsnamn")) {
                TextField("", text: $dataItem.innerInfo, prompt: Text(""))
            }
        }
        
    }
}

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationLink {
                    DataListView(data: testData)
                } label: {
                    Text("Link to data")
                }
            }
        }
    }
}
@main
struct ListNavTestAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

#Preview {
    ContentView()
}
swiftui
1个回答
0
投票

好的,我尝试根据注释修改代码。并从@ObservableObject转换为@Observable。 代码仍然不起作用,但现在错误不同了。现在我在控制台中收到一条消息:

A navigationDestination for “ListNavTestApp.InnerDataItem” was declared earlier on the stack. 
Only the destination declared closest to the root view of the stack will be used.

我的代码现在是这样的:

import SwiftUI

@Observable
class InnerDataItem : Hashable, Identifiable {
    var id = UUID()
    var innerInfo = ""
    
    init(innerInfo: String = "") {
        self.innerInfo = innerInfo
    }
    
    static func == (lhs: InnerDataItem, rhs: InnerDataItem) -> Bool {
        lhs.innerInfo == rhs.innerInfo
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(innerInfo)
    }
}

@Observable
class DataModel : Identifiable {
    let id: UUID = UUID()
    var info = "My String array"
    var innerData: [InnerDataItem] = []
    
    init(info: String = "My String array", innerData: [InnerDataItem]) {
        self.info = info
        self.innerData = innerData
    }
}

let testData = DataModel(
    info: "Data model object",
    innerData: [
        InnerDataItem(innerInfo: "(1) Inner info One"),
        InnerDataItem(innerInfo: "(1) Inner info Two"),
        InnerDataItem(innerInfo: "(1) Inner info Three"),
    ])

struct DataListView: View {
    var data: DataModel
    
    var body: some View {
        DataList(data: data)
    }
}

struct DataList: View {
    var data: DataModel
    
    var body: some View {
        List {
            ForEach(data.innerData) { item in
                NavigationLink(value: item) {
                    DataLine(dataItem: item)
                }
            }
        }
        .navigationDestination(for: InnerDataItem.self) { i in
            DataEditItem(dataItem: i)
        }
    }
}

struct DataLine: View {
    var dataItem: InnerDataItem
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(dataItem.innerInfo).font(.largeTitle)
        }
    }
}

struct DataEditItem: View {
    @Bindable var dataItem: InnerDataItem
    
    var body: some View {
        Form {
            Section(header: Text("Visningsnamn")) {
                TextField("", text: $dataItem.innerInfo, prompt: Text(""))
            }
        }
        
    }
}

struct ContentView: View {
    @State private var gotoDataList = false
    
    var body: some View {
        NavigationStack {
            List {
                Button("Link to data") {
                    gotoDataList.toggle()
                }
            }
            .navigationDestination(isPresented: $gotoDataList) {
                DataListView(data: testData)
            }
        }
    }
}
@main
struct ListNavTestAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

#Preview {
    ContentView()
}

© www.soinside.com 2019 - 2024. All rights reserved.