I found this problem many times in the internet but not a solution for this.
I have a SwiftUI list with data fetched from a server. The app uses a periodically background sync (into a core data background context). So the rows of this list can change. To make it simple to understand think of a message app like on the iPhone:
struct MasterView: View {
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Chat.name, ascending: true)],
animation: .none)
private var chats: FetchedResults<Chat>
var body: some View {
List {
ForEach(chats, id: \.chatID) { chat in
NavigationLink(destination: DetailView(chat: chat)) {
Text(chat.name ?? "")
}
}
}
}
}
The detail view is not so important here but keeping with the example of a message app you would have something like the following code to display the messages of a selected chat:
struct DetailView: View {
let chat: Chat
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Message.timestamp, ascending: true)],
animation: .none)
private var messages: FetchedResults<Message>
var body: some View {
List {
ForEach(messages, id: \.messageID) { message in
Text(message.messageText ?? "")
}
}
.onAppear {
if let chatID = chat.chatID {
messages.nsPredicate = NSPredicate(format: "chatID == %@", chatID)
}
}
}
}
In the internet I saw also other examples without using core data for the master view.
If the details view is visible to the user and the master view receives new data from the server the details view will always close (pops) automatically. This happens also when the chatID has not changed and still exists. A change of the master or also if in a split view the master view scrolls outside the visible area then the detail screen will close.
As you see I specified the item ids in both ForEach lists and added also in some further tests identifiers to the NavigationLink or destination of the NavigationLink. But as soon the master list updates the old NavigationLink seems to get deallocated and therefore the detail views will close.
Does someone know how to fix this? Of course I could add a button inside the masters list, store the selection and place the NavigationLink outside from the list item as I saw in one example, but it seems to be more a quick hack as a good solution.