需要在 SwiftUI 中使用 assign(to:_) 的键路径语法

Need keypath syntax for use in assign(to:_) in SwiftUI

我是 SwiftUI 的新手,一直在关注@peter-friese's example SwiftUI/Firebase app

我的示例应用程序完美运行,但我现在尝试稍微修改,但 无法在 assign/map 中获得正确的键路径语法以设置 属性 .

相关的(并稍微简化),有一个数据模型的结构:

struct Task: Codable, Identifiable {
  var title: String
  var status: Bool
  var flag: Bool
}

和视图模型的 class:

class TaskCellViewModel {
  @Published var task: Task
  var iconName:String = "" 
}

在本教程中,map/assignTaskCellViewModel 中用于将 TaskCellViewModel 实例中 iconName 属性 的值设置为如下:

private var cancellables = Set<AnyCancellable>()

init(task: Task) {
    self.task = task
$task
   .map { task in
            task.status ? "checkmark.circle.fill" : "circle"
        }
   .assign(to: \.iconName, on: self)
   .store(in: &cancellables)
}

这适用于设置 iconNameTask 本身上设置 flag 属性 的正确语法是什么?

我尝试了各种组合,但 none 有效,包括:

.assign(to .\Task.task.flag, on: self)
.assign(to .\task.flag, on: self)
.assign(to .\Task.task.flag, on: TaskCellViewModel)

使用 Task.task.flag 它在运行时失败并出现 EXC_BAD_ACCESS 错误或类型转换编译错误:

Cannot convert value of type AnswerRowViewModel.Type to expected argument type AnswerRowViewModel.

PS 考虑到我正在学习并尝试按照教程进行操作,我希望得到 assign/map 问题的答案 - 而不是 workaround/alternative。

改用sink

.sink { [weak self] flag in
   self?.task.flag = flag
}

这可能是您正在寻找的 assign 个参数:

.assign(to: \Task.flag, on: self.task)

BUT 这在这里不起作用,因为 Task 是一个结构。第一个参数是 ReferenceWritableKeyPath (docs),它不适用于结构的值语义。您的 TaskCellViewModelclass,所以这就是它与 self 一起工作的原因。

,这种情况可以使用sink,在闭包中手动赋值。