簡體   English   中英

SwiftUI:View 沒有完全更新,當它的@ObservedObject 從父級更新時滯后?

[英]SwiftUI: View does not fully update, lags behind when its @ObservedObject is updated from parent?

我有以下代碼:

struct ContentView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    
    @State var selectedItemMOID:NSManagedObjectID?
    
    var body: some View {
        
        NavigationView {
            
            VStack {
                if let selectedItemMOID = selectedItemMOID, let item = viewContext.object(with: selectedItemMOID) as? Item {
                    ItemView(item: item)
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button {
                        if let item = addItem() {
                            selectedItemMOID = item.objectID
                        }
                    } label: {
                        Image(systemName: "plus")
                            .font(.system(size: 14, weight: .bold))
                    }
                }
            }
        }
    }
    
    private func addItem() -> Item? {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
            do {
                try viewContext.save()
                return newItem
            } catch {
                return nil
            }
        }
    }
    
}





struct ItemView: View {
    
    @ObservedObject var item:Item
    @State var itemIDString:String = ""
    
    var body: some View {
        
        List {
            
            VStack {
                
                Text(itemIDString)
                
                Text("the item: \(item.objectID)")
                
            }
            .onChange(of: item, perform: { newValue in
                updateIdString()
            })
            .onAppear {
                updateIdString()
            }
            
        }
        
    }
    
    func updateIdString() {
        
        itemIDString = "\(item.objectID)"
    }
    
    
}

問題

當我按下加號按鈕(右上角)時, ItemView部分更新。 底部的文本視圖立即更新,頂部的滯后。

看到這個行為:

在此處輸入圖像描述

您可以看到頂部的項目 ID 總是落后一個(第一次渲染除外)。 因此,例如,點擊加號(第一次之后),頂部是 p45,底部是 p46。 等等。

為什么頂部文本落后一個?

我也添加了onChange ,以為可以同步,但事實並非如此。 沒有它,設置第一項后,頂部文本永遠不會更新。

    .onChange(of: item, perform: { newValue in
        updateIdString()
    })

我需要理解為什么會發生這種情況,這樣我才能理解如何正確構建一般使用@ObservedObject的視圖,以便在將 ObservedObject 設置為新視圖時立即更新。

所以,要明確我的問題是如何修復此代碼,以便在設置item時整個ItemView立即更新,以及為什么這會在高級別發生,以便我可以避免以后發生同樣類型的錯誤。

解決Asperi 的方法(感謝您的回答:):

他的回答修復了這個特定案例,但是,我不確定我將如何使用該模式 go 。 例如,如果ItemView觀察到多個對象,比如說一個Car和一個User實體,那么.id(car.id)只會對在ItemView上設置新Car做出反應,而不會對設置新User做出必要的反應。 那么,在這種情況下, @ObservedObject的意義何在。 使用建議的.id(car.id)它只會對一個而不是另一個做出反應(如果ItemView有 6 個 @ObservedObjects...,則更多)。

這是否意味着一個視圖應該只有一個@ObservedObject? 我不這么認為。 我錯了嗎?

只是想了解如何擴展id(item.id)模式,如果它是令人滿意的答案。 我還不明白。

我認為這是由於重用/緩存,簡而言之渲染優化,嘗試

    List {
       // content is here
    }
    .id(item)     // << this one !!

是因為你沒有使用newValue,改成:

.onChange(of: item, perform: { newValue in
    itemIDString = "\(newValue.objectID)"
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM