簡體   English   中英

為什么 SwiftUI 綁定數組實例 var 不起作用?

[英]Why is SwiftUI Binding for an array instance var not working?

綁定的行為不像預期的那樣,我希望能深入了解正在發生的事情。

這是說明問題的代碼。 一個名為“Project”的 class Model object 包含一個名為“ name ”的字符串數組。 代碼將 Binding for name傳遞給 ProjectVM 類型的 ViewModel 以在 View 中使用。 在視圖的列表中,我可以刪除一行,對應於刪除字符串數組的一個元素,但它馬上又回來了。

此代碼應該在原始數組上運行,因為它使用綁定,但顯然這不是正在發生的事情。 有任何想法嗎?

如果根 object 是名稱的 @State var(請參閱注釋掉的代碼)而不是 Project 的屬性,則它按預期工作。

使用 Xcode 12.4 和 Swift 5

@main
struct Try_ArrayBindingApp: App {
    @State var project = Project()
    //@State var names = [ "a", "b", "c" ]
    var body: some Scene {
        WindowGroup {
            ProjectV(pVM: ProjectVM(names: $project.names))
            //ProjectV(pVM: ProjectVM(names: $names))
        }
    }
}

class Project { var names = [ "one", "two", "three"] }

class ProjectVM: ObservableObject {
    @Binding var names: [String]
    
    init(names: Binding<[String]> ) { self._names = names }
    
    func delete(at offsets: IndexSet) {
        names.remove(atOffsets: offsets)
    }
}

struct ProjectV: View {
    @ObservedObject var pVM: ProjectVM
    
    var body: some View {
        VStack {
            List {
                ForEach(pVM.names, id: \.self) { n in
                    Text(n)
                }
                .onDelete(perform: delete)
            }
        }
    }
    
    private func delete(at offsets: IndexSet) {
        pVM.delete(at: offsets)
    }
}

通過在父視圖中保存初始@State,然后將其@Binding 到可觀察的 object,然后將其發送到子視圖,至少,數據流肯定會變得混亂。 我實際上不相信它不應該像你想象的那樣表現,但這是一個令人困惑的心理 model 思考,而不是你在 SwiftUI 中常見的東西。

更常見的 model 是將 state 保存在父視圖擁有的 ObservableObject 中:

@main
struct Try_ArrayBindingApp: App {
    @StateObject var project = ProjectVM(names: [ "one", "two", "three"])
    var body: some Scene {
        WindowGroup {
          ProjectV(pVM: project)
        }
    }
}

class ProjectVM: ObservableObject {
    @Published var names: [String]
    
    init(names: [String]) {
        self.names = names
    }
    
    func delete(at offsets: IndexSet) {
        names.remove(atOffsets: offsets)
    }
}

struct ProjectV: View {
    @ObservedObject var pVM: ProjectVM
    
    var body: some View {
        VStack {
            List {
                ForEach(pVM.names, id: \.self) { n in
                    Text(n)
                }
                .onDelete(perform: delete)
            }
        }
    }
    
    private func delete(at offsets: IndexSet) {
        pVM.delete(at: offsets)
    }
}

請注意, names現在是@Published屬性。

暫無
暫無

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

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