I have a Main View that initialises a ViewModel which every 30 seconds updates a list of items. The model (in order to have the same reference of items in the entire app) is passed around as an @EnvironmentalObject.
However when I am in the MainView->ListView->DescriptionView and the user for example tries to login, that affects the list of items and in sequence the views are forcing a redraw which results in the DescriptionView to be dismissed.
import SwiftUI
class ItemViewModel: ObservableObject {
@Published var items: [Item]
var timer: Timer?
func polling() {
refreshItemList()
}
init() {
self.timer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(polling), userInfo: nil, repeats: true)
}
}
struct MainView {
@StateObject var model: ItemViewModel
@Environment(.presentationMode) var presentationMode: Binding<PresentationMode>
var body: View {
ListOfItemsView().environmentObject(model)
}
}
struct ListOfItemsView {
@EnvironmentObject var model: ItemViewModel
@Environment(.presentationMode) var presentationMode: Binding<PresentationMode>
var body: View {
List(items) { item in
NavigationLink(destination:
ItemDescriptionView(item).environmentObject(model)
) {
Text(item.title)
}
}
}
}
struct ItemDescriptionView {
let item: Item
@Environment(.presentationMode) var presentationMode: Binding<PresentationMode>
func logIn() {
//Results into changes on the ItemViewModel and item list
}
}
2
Answers
I was facing same type of issue, any change in the view model cause all view to redraw and dismissing that particular view. The whole problem lies behind these "NavigationLink" links.
After lots of research I finally resolved that issue by putting all view in "NavigationView".
So I would suggest you to put your main view in "NavigationView" and test it. Let me know whether it resolve your issue or not.
A flaw in NavigationView was that an active NavigationLink that scrolls off screen is deactivated. The only way to fix it is to use the new NavigationStack or NavigationSplitView instead.
By the way
TimelineView
can do what you want without needing to make an object.