繁体   English   中英

ObservableObject 正在更新所有视图并导致菜单在 SwiftUI 中关闭

[英]ObservableObject is updating all views and causing menus to close in SwiftUI

我有这个 class,它每 3 秒调用一次 API(使用计时器)并将结果保存在名为items@Published数组中:

public class ApiAdapter: ObservableObject {

    @Published var items = [Item]()
    
    init() {
        
        api = Api(...)
        
        Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { timer in
            api.getItems() { items in 
                if let _items = items {
                    self.items = _items
                }
            }
        }
    }

}

ApiAdapter 用于整个应用程序,因此我决定将其@EnvironmentObject
在我的应用程序的主视图中,我正在访问apiAdapter.items数组以将其显示在如下列表中:

struct MainListView: View {

    @EnvironmentObject var apiAdapter: ApiAdapter
    
    var body: some View {
        NavigationView {
            List {
                ForEach(apiAdapter.items, id: \.hash) { i in
                    Text(i.name)
                    ...
                }
            }
            .navigationBarItems(trailing:
                                Menu {
                                    Picker(selection: $category, label: Text("Filter")) {
                                        Text("Category 1").tag(1)
                                        Text("Category 2").tag(2)
                                        Text("Category 3").tag(3)
                                    }
                                } label: {
                                    Image(systemName: "line.horizontal.3.decrease.circle")
                                        .imageScale(.large)
                                }
        }
    }
}

在 MainListView 中,我在navigationBar中也有一些Menu s,每次apiAdapter更新items变量时它们都会关闭,因此很难使用它们。

怎么可能只更新列表而不是整个视图? 或者更好的是,如何只更新在上次 api 通话中更改的项目?

从 MainListView 中删除EnvironmentObject 仅为列表创建一个新视图,如下所示:

struct ListView : View {
    @EnvironmentObject var apiAdapter: ApiAdapter

    var body : some View {
        List {
            ForEach(apiAdapter.items, id: \.hash) { i in
                Text(i.name)
            }
        }
    }
}

现在您的子视图仅更新,而您的主视图保持不变并且菜单保持打开状态。

而您的 MainListView 如下所示:

struct MainListView: View {
    var body: some View {
        NavigationView {
            ListView() //<< here comes your ListView which refreshes independent
            .navigationBarItems(trailing:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM