当我的红色、绿色或蓝色变量发生变化时,我正在尝试使用组合来更新颜色。我看过的示例使用了sink(),这似乎适合我,但是eraseToAnySubscriber是MIA,我找不到替代方法。
看起来有效的方法是对一个计算变量使用赋值(),但这看起来像是一个小技巧。
init() {
redCancellable = red.hasChanged.receive(on: RunLoop.main).assign(to: \.rgbUpdated, on: self)
}有没有办法保存sink()返回的值?
发布于 2019-07-27 02:44:57
这听起来像是CombineLatest的工作。是的,sink是以您喜欢的方式处理管道末端的一种完美的方法。
这里有一个简单的例子。我将从一个具有r、g和b变量的对象开始:
class ColorObject {
@Published var r : CGFloat = 1
@Published var g : CGFloat = 1
@Published var b : CGFloat = 1
}现在想象一下,我们在某个地方有一个该对象的实例;将其命名为colorObject。然后我们可以配置发布者:
let rpub = colorObject.$r
let gpub = colorObject.$g
let bpub = colorObject.$b
let colorpub = Publishers.CombineLatest3(rpub,gpub,bpub)
.map { UIColor(red: $0.0, green: $0.1, blue: $0.2, alpha: 1) }结果是,每当colorObject的r、g或b发生变化时,就会有一个UIColor出现在管道中。现在我们可以通过使用sink订阅它来接收来自colorpub的通知,并随心所欲地处理结果。让我们将一些接口对象的颜色设置为该颜色:
let sink = colorpub.sink { self.view.backgroundColor = $0 }或者,我可以使用assign编写它,虽然backgroundColor是一个可选的,所以我必须插入一个map操作符,因为keyPaths不是协变的:
let assign = colorpub.map{Optional($0)}
.assign(to: \.backgroundColor, on: self.view)现在,每当colorObject的r、g或b发生变化时,我们的视图的颜色也会相应地发生变化。
这并不是实现这个目标的唯一方法,- far!但这只是一个简单的例子,说明如何使用组合来完成任务。一种可能有用的变体是将colorpub publisher上移到ColorObject中;这样,ColorObject就可以直接自动售卖颜色:
class ColorObject {
@Published var r : CGFloat = 1
@Published var g : CGFloat = 1
@Published var b : CGFloat = 1
lazy var colorpub = Publishers.CombineLatest3($r,$g,$b)
.map { UIColor(red: $0.0, green: $0.1, blue: $0.2, alpha: 1) }
}这不会改变sink或assign的相关信息
let sink = colorObject.colorpub.sink { // ... whatever
// or
let assign = colorObject.colorpub.map{Optional($0)}
.assign(to: \.backgroundColor, on: self.view)https://stackoverflow.com/questions/57222005
复制相似问题