【问题标题】:Need keypath syntax for use in assign(to:_) in SwiftUI需要在 SwiftUI 中的 assign(to:_) 中使用 keypath 语法
【发布时间】:2021-04-08 13:06:56
【问题描述】:

我是 SwiftUI 新手,一直在关注 @peter-frieseexample SwiftUI/Firebase app

我的示例应用运行良好,但我现在尝试稍微修改,但我无法在assign/map 中获取正确的键路径语法以设置属性。

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

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

还有一个视图模型的类:

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

在本教程中,TaskCellViewModel 中使用map/assign 来设置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 属性的正确语法是什么?

我尝试了各种组合,但都没有奏效,包括:

.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 错误或类型转换编译错误:

无法将 AnswerRowViewModel.Type 类型的值转换为预期的参数类型 AnswerRowViewModel

PS 鉴于我正在学习并尝试按照教程进行操作,我希望得到分配/映射问题的答案 - 而不是解决方法/替代方案。

【问题讨论】:

  • 在Task中设置属性的值。它发生在更新发生时创建任务之后。在本教程中,它适用于 TaskCellViewModel 的属性 - 我正在尝试使用相同的方法,但适用于 Task 的属性。

标签: swift swiftui combine


【解决方案1】:

改用sink

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

【讨论】:

    【解决方案2】:

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

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

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

    As Asperi already answered,你可以在这种情况下使用sink,并在闭包中手动赋值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2016-11-25
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 2018-08-19
      相关资源
      最近更新 更多