SwiftUI添加列表行后View组件未更新问题求助
SwiftUI点击添加按钮后SetsRowView不新增的解决方案
核心问题分析
你当前的ExerciseCardViewModel中,@Published var exercise: Exercise仅会在exercise实例本身被替换时触发视图更新。但你修改的是exercise内部的sets数组(若Exercise为类类型),这种内部属性的变化不会触发@Published的通知,导致视图无法感知数组变更。
解决方案
方案1:让Exercise成为ObservableObject(推荐)
将Exercise类改为遵循ObservableObject,并把sets标记为@Published,这样内部数组的变化会自动通知视图:
class Exercise: ObservableObject { @Published var sets: [DBSet] = [] // 你的其他Exercise属性(如名称、类型等) }
然后修改ExerciseCardViewModel,将exercise改为@ObservedObject:
class ExerciseCardViewModel: ObservableObject { @ObservedObject var exercise: Exercise init(exercise: Exercise) { self.exercise = exercise } func addSet() { exercise.sets.append(DBSet(number: exercise.sets.count + 1)) } func deleteSet() { exercise.sets.removeLast() } func createSetViewModel(sets: DBSet) -> SetViewModel { SetViewModel(sets: sets) } }
调用addSet()修改sets数组时,Exercise的@Published会自动发送更新通知,视图会重新渲染新增行。
方案2:手动触发ViewModel的更新通知
如果不想修改Exercise的结构,可在修改sets数组后手动调用objectWillChange.send()通知视图更新:
class ExerciseCardViewModel: ObservableObject { @Published var exercise: Exercise init(exercise: Exercise) { self.exercise = exercise } func addSet() { exercise.sets.append(DBSet(number: exercise.sets.count + 1)) objectWillChange.send() } func deleteSet() { exercise.sets.removeLast() objectWillChange.send() } func createSetViewModel(sets: DBSet) -> SetViewModel { SetViewModel(sets: sets) } }
额外检查项
- 确保
DBSet遵循Identifiable协议,或在ForEach中明确指定id参数,否则SwiftUI无法识别数组元素变化:
(假设ForEach(viewModel.exercise.sets, id: \.id) { set in SetsRowView(sets: viewModel.createSetViewModel(sets: set)) .listRowBackground(Color.theme.TBBlack) }DBSet有唯一属性id) - 确认父视图中
ExerciseCard的viewModel通过@StateObject创建,保证实例唯一性:// 父视图示例代码 @StateObject private var exerciseVM = ExerciseCardViewModel(exercise: Exercise()) var body: some View { ExerciseCard(viewModel: exerciseVM, deleteExercise: { _ in }) }
内容的提问来源于stack exchange,提问作者Frederik Hjorth
相关产品推荐
相关产品推荐

