You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM场景下SwiftUI List视图无法更新的问题求助

问题解决:SwiftUI添加行后列表不更新

核心问题在于你的ViewModel结构:@Published var itemContent = ItemContent()只会在itemContent本身被替换时触发UI更新,而itemContent内部的children数组变化,无法传递到ViewModel的发布流中,导致List感知不到数据变化。

解决方案一:转发ItemContent的变化事件

在ViewModel中订阅itemContent的objectWillChange事件,将其转发到自身的发布流,这样内部属性变化就能触发UI刷新:

extension ContentView {
    class ViewModel: ObservableObject {
        @Published var itemContent = ItemContent()
        @Published var selectedRows = Set<ContentRow>()
        private var cancellables = Set<AnyCancellable>()
        
        init() {
            // 订阅itemContent的内部变化,转发给ViewModel的发布流
            itemContent.objectWillChange
                .sink { [weak self] _ in
                    self?.objectWillChange.send()
                }
                .store(in: &cancellables)
        }
        
        func add() {
            let row = ContentRow()
            itemContent.children.append(row)
        }
    }
}

解决方案二:简化数据结构(更推荐)

如果ItemContent仅作为children的容器,可以直接将children移到ViewModel中,减少嵌套层级,避免事件传递问题:

  1. 移除ItemContent类
  2. 修改ViewModel和ContentView:
// MARK: - views/ view model.

struct ContentView: View {
    @StateObject var vm = ViewModel()
    
    var body: some View {
        NavigationStack {
            List(selection: $vm.selectedRows) {
                ForEach(vm.children, id: \.id) { row in
                    RowView(row: row)
                }
            }
            .toolbar {
                ToolbarItem {
                    Button("add", action: vm.add)
                }
            }
        }
    }
}

extension ContentView {
    class ViewModel: ObservableObject {
        @Published var children: [ContentRow] = []
        @Published var selectedRows = Set<ContentRow>()
        
        func add() {
            let row = ContentRow()
            children.append(row)
        }
    }
}

原理说明

SwiftUI的@Published对于引用类型(如ObservableObject实例),仅在引用本身改变时(比如给itemContent赋值新的ItemContent())才会触发更新。当你修改itemContent内部的children数组,itemContent的引用没有变化,因此ViewModel不会通知UI刷新。通过订阅转发或简化层级,就能让UI感知到内部数据的变化。

内容的提问来源于stack exchange,提问作者MatFetsch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:01:13