I’m a fairly inexperienced SwiftUI programmer, so I’m almost constantly confused by one thing or another. This time it’s Navigation.
I want my start screen to show a List with some static content, where each line navigates to a dynamic List, where in turn I want to navigate to a view to show or edit the content of the line.
In my app, when I tap on a line to show/edit it, the app returns to the start view. I somehow messes up the navigation stack, or does somethings else wrong – but what?
I’ve recreated the behaviour in a small demo app:
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()
}