- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
当我的红色、绿色或蓝色变量发生变化时,我正在尝试使用 Combine 来更新颜色。我看过的示例使用 sink() ,这似乎适合我,但 eraseToAnySubscriber 是 MIA,我找不到替代方法。
似乎可行的是对计算变量使用 assign() ,但这似乎有点 hack。
init() {
redCancellable = red.hasChanged.receive(on: RunLoop.main).assign(to: \.rgbUpdated, on: self)
}
有没有办法保存sink()返回的值?
最佳答案
这听起来像是 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
发生变化时,我们 View 的颜色也会随之变化。
这不是实现此目标的唯一方法——远非如此!但这是使用 Combine 完成工作的一个简单示例。一个可能有用的变体是将 colorpub
发布者向上移动到 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)
关于快速组合 : Alternatives too eraseToAnySubscriber?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57222005/
当我的红色、绿色或蓝色变量发生变化时,我正在尝试使用 Combine 来更新颜色。我看过的示例使用 sink() ,这似乎适合我,但 eraseToAnySubscriber 是 MIA,我找不到替代
我是一名优秀的程序员,十分优秀!