我在 SwiftUI 中有一个模型处理我的人物模型。为了能够将编辑器中的草稿人存储在视图中,我有两个对象:
@Published var person: Person
@Published var draftPerson: Person
在用户界面中,我仅更改草稿人,直到用户单击“保存”,这会将草稿人存储为人员。在编辑器的onAppear方法中,我将draftPerson重置为person。
现在我想禁用编辑器的“保存”按钮,因此在模型中引入了“已修改”布尔值。使用管道,如果并且只要 DraftPerson 不等于 person,我想通过执行以下操作将修改设置为 true:
$draftPerson.map { draftPerson in
return draftPerson != self.person
}
.assign(to: \.modified, on: self)
.store(in: &cancellables)
乍一看似乎可以正常工作,但如果我更改了文本字段中的某些内容,则仅在该字段中第二次更改后,modified 的值才会设置为 true。反之亦然,如果我删除键入的值,只有在我再删除一个原来存在的字符后,它才会设置回 false。
问题1: 是否有另一种“最佳实践”来处理草稿对象的更改并停用 SwiftUI 中的“保存”按钮?
问题2: 为什么管道“落后一变”?
非常感谢您的投入。
编辑:我创建了应用程序的一个单独部分,仅关注管道,并意识到如果我删除其他管道,它确实会按预期工作。我现在必须详细检查一下。尽管如此,我还是会坚持我的第一个问题: 有什么我可以做得更好的吗?
请在 Github 上找到代码
您可以声明另一个
@Published
属性,并将两个 person 和 DraftPerson 发布者合并起来,并发布它们是否相同,如下所示:
@Published var person: Person
@Published var draftPerson: Person
@Published var saveDisabled: Bool = true
public init() {
// all init code
Publishers.CombineLatest($person, $draftPerson)
.map { $0 == $1 }
.assign(to: &$saveDisabled)
}
但本质上它是不需要的,计算属性将完成相同的工作:
var saveDisabled: Bool {
person == draftPerson
}
因为 person 和 DraftPerson 都被标记为
@Published
,每次其中之一发生更改时,View
都会收到更改通知,因此它也会选择 saveDisabled 的新值。