我正在为 iOS 构建一个图形应用程序。这是我的代码。
class Group {
/// All the shapes contained in the group
public var shapes: CurrentValueSubject<[Shape], Never>
/// The frame of the group
var frame: CurrentValueSubject<CGRect, Never>
/// The path to be calculated and displayed to users from the contained shapes
var cgPath: CurrentValueSubject<CGPath, Never>
}
class Shape {
var path: CurrentValueSubject<Path, Never> = .init(Path())
}
struct Path {
public var points = [CGPoint]()
}
所以,这就是我想做的,但不知道如何使用 Combine 来完成。
我想让 Group
观察它自己的 frame
、shapes
和它的形状的 path
(我需要合并所有这些),所以每次它们发生变化时,我都可以计算出要显示的新 CGPath 并将其分配给 cgPath
属性(绘制所有内容的 View 将观察到)。
请让我知道这是否可行,或者是否有更好的方法来解决这一切。
提前致谢。
最佳答案
使用 CombineLatest
只需将 @Published
属性包装器添加到您感兴趣的属性中。Combine 已经有一个预定义的 CombineLatest3
方法来创建一个 Publisher
你可以订阅。玩得开心。
import Foundation
import Combine
import CoreGraphics
class Group {
init(shapes: [Shape], frame: CGRect, path: Path) {
self.shapes = shapes
self.frame = frame
self.path = path
self.observer = Publishers.CombineLatest3($shapes, $frame, $path)
.sink(receiveCompletion: { _ in }, receiveValue: { (combined) in
let (shapes, frame, path) = combined
// do something
print(shapes, frame, path)
})
}
@Published var shapes: [Shape]
@Published var frame: CGRect
@Published var path: Path
private var observer: AnyCancellable!
}
class Shape {
var path: CurrentValueSubject<Path, Never> = .init(Path())
}
struct Path {
var points = [CGPoint]()
}
注意每次更改如何触发接收器关闭。
let group = Group(shapes: [Shape(), Shape()], frame: CGRect.zero, path: Path())
group.shapes = [Shape(), Shape(), Shape()]
group.frame = CGRect(x: 1, y: 1, width: 1, height: 1)
group.path.points = [CGPoint(x: 1, y: 1)]
关于Swift Combine - 观察 N 个对象数组中对象的属性并与其他属性合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60164640/