英文:
SwiftUI - Model changes in Main View dismisses Navigation Stack
问题
我有一个主视图,初始化了一个ViewModel,每30秒更新一次项目列表。为了在整个应用中具有相同的项目引用,模型被传递为@EnvironmentalObject。
然而,当我在MainView->ListView->DescriptionView中,例如尝试登录,会影响项目列表,然后视图会强制刷新,导致DescriptionView被关闭。
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
}
}
英文:
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
}
}
答案1
得分: 1
我遇到了相同类型的问题,视图模型中的任何更改都会导致所有视图重新绘制并关闭特定视图。整个问题都在于这些 "NavigationLink" 链接。
经过大量研究,我最终通过将所有视图放入 "NavigationView" 中解决了这个问题。
所以我建议你将主视图放入 "NavigationView" 中并进行测试。请告诉我是否解决了你的问题。
英文:
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.
答案2
得分: 0
NavigationView存在的一个问题是,当处于活动状态的NavigationLink滚动到屏幕之外时,会被停用。唯一的解决方法是使用新的NavigationStack或NavigationSplitView。
顺便说一下,TimelineView
可以实现您想要的功能,无需创建对象。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论