SwiftUI数组不更新父视图[重复]

5hcedyr0  于 9个月前  发布在  Swift
关注(0)|答案(2)|浏览(110)

此问题在此处已有答案

SwiftUI View updating(1个答案)
9天前关闭
这篇文章是编辑并提交审查9天前.
我面临的问题是,数组项的更改不会传播到父视图。内部视图中的文本确实会更新。但是,对同一项的更改不会显示在父视图中。
这是我的问题的一个非常简化的版本。在我看来,删除数组或手动发送objectWillChange不是一个好的解决方案,因为它很可能会忘记它。将ViewModel更改为struct对我来说不起作用,因为我正在从多个地方更新ViewModel。

import SwiftUI

class ViewModel: Identifiable, ObservableObject {
    var label: String = ""
    @Published var big: Bool

    init(label: String, big: Bool) {
        self.big = big
        self.label = label
    }
}

class ArrayViewModel: ObservableObject {
    @Published var items: [ViewModel]

    init(items: [ViewModel] = [ViewModel]()) {
        self.items = items
    }

    init() {
        self.items = [ViewModel]()
    }
}

struct ContentView: View {
    @StateObject var items = ArrayViewModel(items: [ViewModel(label: "view ex", big: true)])
    var body: some View {
        VStack {
            ForEach(0 ..< items.items.count, id: \.self) { index in
                Text(items.items[index].big ? "big" : "small")
                Button("outer toggle") {
                    items.items[index].big.toggle()
                }
                InnerCard()
                    .environmentObject(items.items[index])
            }
        }
    }
}

struct InnerCard: View {
    @EnvironmentObject var currentItem: ViewModel
    var body: some View {
        Text(currentItem.big ? "big" : "small")
        Button("inner toggle") {
            currentItem.big.toggle()
        }
    }
}

#Preview {
    ContentView()
}

字符串


的数据

ndasle7k

ndasle7k1#

  • 在我看来 * 使用多个可观察对象和一个视图模型类而不是一个模型结构 * 不是一个好的解决方案 *。

我推荐这个:ViewModel变成了Model,一个当成员改变时刷新视图的结构体,ArrayViewModel变成了ViewModel,一个唯一的真实来源。
子视图与一个简单的标准@Binding连接

struct Model: Identifiable {
    let id = UUID()
    var label: String
    var big: Bool
    
    var state : String {
        big ? "big" : "small"
    }
}

class ViewModel: ObservableObject {
    @Published var items: [Model]

    init(items: [Model] = []) {
        self.items = items
    }
}

struct ContentView1: View {
    @StateObject var viewModel = ViewModel(items: [Model(label: "view ex", big: true)])
    
    var body: some View {
        VStack {
            ForEach($viewModel.items) { $item in
                Text(item.state)
                Button("outer toggle") {
                    item.big.toggle()
                }
                InnerCard(currentItem: $item)
            }
        }
    }
}

struct InnerCard: View {
    @Binding var currentItem: Model

    var body: some View {
        Text(currentItem.state)
        Button("inner toggle") {
            currentItem.big.toggle()
        }
    }
}

字符串

vuktfyat

vuktfyat2#

父视图未被更新,因为发布的属性是类的集合。类是引用值;只要数组中存在相同的类,数组(以及包含的ViewModel)在技术上不会更改。结构(以及其他类型)是值类型,并将按预期传播行为。
由于有很多方法可以达到你所希望的行为,这取决于你的用例,剩下的就交给你了。

相关问题