我有一个VielModel在SwiftUI处理我的人模型。为了能够在视图的编辑器中存储草稿人员,我有两个对象:
@Published var person: Person
@Published var draftPerson: Person
在UI中,我只更改draftPersons,直到用户单击"保存",这将draftPerson存储为person。在编辑器的onAppear方法中,我将draftPerson重置为person。
现在我想禁用"保存"按钮,因此引入了bool "modified"在虚拟机中。使用管道,如果且只要draftPerson不等于person,我想通过执行以下操作将modified设置为true:
$draftPerson.map { draftPerson in
return draftPerson != self.person
}
.assign(to: .modified, on: self)
.store(in: &cancellables)
乍一看,它似乎正在工作,但如果我在textField中更改某些内容,则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的新值。