簡體   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