首页 > 解决方案 > 在swiftui中修改项目类后ListView不更新

问题描述

我有一个任务项目的列表视图。每 10 秒一个计时器触发函数 randomTasks 负责修改列表中每个任务的标题和描述,但 ListView 不反映更改。我尝试使用 objectWillChange.send() 但它不起作用.

我注意到,当使用不同的 id 修改任务时,ListView 会更新,我可以看到更改,但是当我在详细视图中时,只要触发 randomTaskTitle,视图就会自动关闭。

class Task {
    var id: String = UUID().uuidString
    var title: String
    var description: String

    init(title: String, description: String) {
        self.title = title
        self.description = description
    }
}

import SwiftUI

struct TasksView: View {
    
    @EnvironmentObject var viewModel: TasksViewModel

        let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect()
    
    var body: some View {
        
        NavigationView {
          List {
            ForEach(viewModel.tasks, id: \.id) { task in          
               NavigationLink(
                  destination: DetailView(task: task)
               ) {
                  VStack {
                    Text(task.title)
                    Text(task.description)
                  }
               }
          }
        }
        .onReceive(timer) { time in
            Task {
                await viewModel.randomTasks()
            }
        }
        
    }
}

struct TasksViewNew_Previews: PreviewProvider {
    static var previews: some View {
        TasksView()
    }
}
import Foundation

@MainActor
class TasksViewModel: ObservableObject {

    @Published var tasks = [Task]()

    init() {
      self.tasks = [Task(title: "TaskA", description: "DescriptionA"),
                    Task(title: "TaskB", description: "DescriptionB"),
                    Task(title: "TaskC", description: "DescriptionC"),
                    Task(title: "TaskD", description: "DescriptionD"),]
    }
    
    func randomTasks() {
      tasks.forEach { task in
        task.title = randomTitleTask()
        task.description = randomDescriptionTask()
      }
    }
    
}

标签: swiftswiftui

解决方案


类中的@Published数组不知道您的对象何时更改。它只能跟踪您何时添加/删除它们。

  1. 您可以通过在修改之前ObservableObject调用来明确地告诉您某些内容已更改objectWillChange.send()
objectWillChange.send()
tasks.forEach { task in
    task.title = UUID().uuidString
    task.description = UUID().uuidString
}
  1. 将您的类转换为结构,并按索引更改项目,例如
tasks.indices { i in
    tasks[i].title = UUID().uuidString
    tasks[i].description = UUID().uuidString
}
  1. 看看ObservableArray这个答案

推荐阅读