SwiftUI – 主视图中的模型更改会关闭导航堆栈

huangapple go评论71阅读模式
英文:

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&lt;PresentationMode&gt;

    var body: View {
        ListOfItemsView().environmentObject(model)
    }
}

struct ListOfItemsView {
    @EnvironmentObject var model: ItemViewModel
    @Environment(\.presentationMode) var presentationMode: Binding&lt;PresentationMode&gt;
    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&lt;PresentationMode&gt;
    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.

huangapple
  • 本文由 发表于 2023年4月6日 22:27:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75950683.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定