SplitView in SwiftUI, only works when clicking on first item, second selection never does anything

103 views Asked by At

I have list view in SwiftUI and it shows a list of journal entries, it works only when I click first entry. When I click second entry, it never works again. It gets stuck on first entry selected. I have checked and those underlying data for list and journal entries are definitely unique and different.

import RealmSwift

final class JournalEntry: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var id = UUID().uuidString
    @Persisted var date: Date
    @Persisted var name: String
    @Persisted var body: String
    @Persisted var bodySummarizedByAI: String?
    @Persisted var responseToBodyByAI: String?
    @Persisted(originProperty: "entries") var journal: LinkingObjects<Journal>
    
    override static func primaryKey() -> String? {
            return "id"
        }
    
    required override init() {
        super.init()
    }
    
    internal init(name: String, date: Date, body: String, bodySummarizedByAI: String? = nil, responseToBodyByAI: String? = nil) {
        super.init()
        self.name = name
        self.date = date
        self.body = body
        self.bodySummarizedByAI = bodySummarizedByAI
        self.responseToBodyByAI = responseToBodyByAI
    }
}

struct JournalListView: View {
    @ObservedResults(JournalEntry.self) var journalEntries
    
    @State private var selectedEntryID: ObjectId?
    @State private var showingAddNewJournalEntry = false
    
    var body: some View {
        List(journalEntries, id: \.id, selection: $selectedEntryID) { entry in
            NavigationLink(destination: JournalEntryView(entryToEdit: entry)) {
                VStack(alignment: .leading) {
                    Text(entry.name)
                        .font(.system(size: 25))
                        .multilineTextAlignment(.leading)
                    Text(entry.date.description)
                        .font(.system(size: 10))
                        .multilineTextAlignment(.leading)
                    Text(entry.body)
                        .truncationMode(.tail)
                        .lineLimit(3)
                }
            }
            .cornerRadius(15)
            .padding(.horizontal, 15)
        }
        .listRowInsets(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
        .toolbar {
            ToolbarItem(placement: .automatic) {
                Button {
                    showingAddNewJournalEntry = true
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
        .sheet(isPresented: $showingAddNewJournalEntry, content: {
            JournalEntryView()
        })
    }
}
1

There are 1 answers

6
Benzy Neez On

I tried to reproduce the issue by improvising some of the missing parts (in particular, the data item JournalEntry and the detail view JournalEntryView) and by commenting out the parts that weren't relevant (the .toolbar and .sheet modifiers).

The only thing needed to make it work was to nest it all in a NavigationStack, could this be the problem?

Also, since the data is presumably Identifiable, you don't need to specify the id explicitly when building the List.

This works for me:

EDIT revised to use your JournalSplitView as the top-level view.

struct JournalSplitView: View {
    var body: some View {
        NavigationSplitView {
            JournalListView()
        } detail: {
            Text("Select journal entry")
        }
    }
}

struct JournalEntry: Identifiable {
    let id = UUID()
    let name: String
    let date: Date = Date.now
    let body: String = "body"
}

struct JournalEntryView: View {
    let entryToEdit: JournalEntry
    var body: some View {
        Text(entryToEdit.name)
    }
}

struct JournalListView: View {
    let journalEntries: [JournalEntry] = [
        JournalEntry(name: "first"),
        JournalEntry(name: "second"),
        JournalEntry(name: "third")
    ]

    @State private var selectedEntryID: UUID?

    var body: some View {
        NavigationStack {
            List(journalEntries, selection: $selectedEntryID) { entry in
                NavigationLink(destination: JournalEntryView(entryToEdit: entry)) {
                    VStack(alignment: .leading) {
                        Text(entry.name)
                            .font(.system(size: 25))
                            .multilineTextAlignment(.leading)
                        Text(entry.date.description)
                            .font(.system(size: 10))
                            .multilineTextAlignment(.leading)
                        Text(entry.body)
                            .truncationMode(.tail)
                            .lineLimit(3)
                    }
                }
                .cornerRadius(15)
                .padding(.horizontal, 15)
            }
            .listRowInsets(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
//            .toolbar {
//                ToolbarItem(placement: .automatic) {
//                    Button {
//                        showingAddNewJournalEntry = true
//                    } label: {
//                        Image(systemName: "plus")
//                    }
//                }
//            }
//            .sheet(isPresented: $showingAddNewJournalEntry, content: {
//                JournalEntryView()
//            })
        }
    }
}

If that doesn't help you to spot the problem then please update your code example to make it complete, so that the problem can be reproduced.