我正在尝试学习SwiftUI和合并语法,并尝试了解如何创建一个可重用的发布器,该发布器将检查字符串是否为空。
我有一个带有5个TextField的SwiftUI,它使用@Binding将它们连接到我的数据模型对象。
class DataWhatIsLoanPayment: ObservableObject {
// Input
@Published var pv = ""
@Published var iyr = ""
// a bunch more fields...
// Output
@Published var isvalidform = false
}
我想在填写完所有字段后启用“计算”按钮(isEmpty == false)。
我跟随https://peterfriese.dev/swift-combine-love/,通过创建一个isValidPVPublisher
和一个isValidIYRPublisher
并将它们组合成一个isValidFormPublisher
,我能够让我的SwiftUI正确地启用/禁用我的Calculate按钮,如下所示:
private var isValidPVPublisher: AnyPublisher<Bool, Never> {
$pv
.debounce(for: 0.8, scheduler: RunLoop.main)
.removeDuplicates()
.map { input in
return input.isEmpty == false
}
.eraseToAnyPublisher()
}
private var isValidIYRPublisher: AnyPublisher<Bool, Never> {
$iyr
.debounce(for: 0.8, scheduler: RunLoop.main)
.removeDuplicates()
.map { input in
return input.isEmpty == false
}
.eraseToAnyPublisher()
}
private var isValidFormPublisher: AnyPublisher<Bool, Never> {
Publishers.CombineLatest(isValidPVPublisher, isValidIYRPublisher)
.map { pvIsValid, iyrIsValid in
return pvIsValid && iyrIsValid
}
.eraseToAnyPublisher()
}
init() {
isValidFormPublisher
.receive(on: RunLoop.main)
.assign(to: \.isValidForm, on: self)
.store(in: &cancellableSet)
}
但是,我的应用程序中的字段将远远超过2个,而且我还将有很多其他的表单,我需要在这些表单中检查字段是否为空。一遍又一遍地重复.debounce(for: 0.8, scheduler: RunLoop.main).removeDuplicates().map { input in return input.isEmpty == false }.eraseToAnyPublisher()
是个坏主意。
我想创建一个可重用的NotEmptyPublisher
,或者类似的东西,它接受一个字段绑定,就像我的$pv
一样,并像上面的isValidPVPublisher
那样设置链。所以我可以有这样的东西:
// Something like this, but I'm not sure of the syntax...
private var isValidPVPublisher = NotEmptyPublisher(field:$pv)
// instead of ...
private var isValidPVPublisher: AnyPublisher<Bool, Never> {
$pv
.debounce(for: 0.8, scheduler: RunLoop.main)
.removeDuplicates()
.map { input in
return input.isEmpty == false
}
.eraseToAnyPublisher()
}
但是我在解析很多我不熟悉的Swift语法时遇到了麻烦,我似乎不知道如何做到这一点,我在网上找到的每个例子都只是内联地定义发布者链,而不是以一种可重用的方式。
如何创建一个可重用的发布器,以便不必重复这些内联发布器(它们都做同样的事情)?
1条答案
按热度按时间ldioqlga1#
你在这里!
$0
是闭包的第一个参数的简写,$1
表示第二个参数,依此类推。!
是Bool
求逆运算符,前缀!
是后缀== false
的简写。现在,关于重用的问题,你不需要做太多的事情,你可以只创建一个函数。
P
是一个泛型,这意味着它可以是任何类型,只要该类型符合Publisher
。where
子句允许我们进一步约束这种一致性,表示当Output
是String
时,我们只能对Publisher
进行操作。some Publisher
保存我们提供了一个不透明的返回类型,如果愿意,可以将其更改为AnyPublisher<Bool, Never>
并使用.eraseToAnyPublisher()
,但我建议只在需要时使用擦除。