具有超过 4 个值的 SwiftUI 和 CombineLatest
SwiftUI and CombineLatest with more than 4 values
我开始尝试使用 SwiftUI,但我遇到了需要 5 个滑块的最新组合的情况。我使用 CombineLatest4
使用 4 个滑块完成所有工作,然后意识到我需要另一个滑块,但没有 CombineLatest5
.
感谢任何帮助。
澄清工作 4 滑块版本:
Publishers
.CombineLatest4($slider1, $slider2, $slider3, $slider4)
.debounce(for: 0.3, scheduler: DispatchQueue.main)
.subscribe(subscriber)
CombineLatest2(CombineLatest3, CombineLatest2)
应该可以解决问题,不是吗?
您可以使用类似的东西:
extension Publisher {
public func combineLatest<P, Q, R, Y>(
_ publisher1: P,
_ publisher2: Q,
_ publisher3: R,
_ publisher4: Y) ->
AnyPublisher<(Self.Output, P.Output, Q.Output, R.Output, Y.Output), Self.Failure> where
P: Publisher,
Q: Publisher,
R: Publisher,
Y: Publisher,
Self.Failure == P.Failure,
P.Failure == Q.Failure,
Q.Failure == R.Failure,
R.Failure == Y.Failure {
Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4).map { tuple, publisher4Value in
(tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
}.eraseToAnyPublisher()
}
}
并这样称呼它:
publisher1.combineLatest(publisher2, publisher3, publisher4, publisher5)
注意 - 从问题中提取的解决方案
好的,弄清楚语法,@Daniel-t 是对的。我只需要创建子发布者:
let paramsOne = Publishers
.CombineLatest3($slider1, $slider2, $slider3)
let paramsTwo = Publishers
.CombineLatest($slider4, $slider5)
paramsOne.combineLatest(paramsTwo)
.debounce(for: 0.3, scheduler: DispatchQueue.main)
.subscribe(subscriber)
请注意,我还必须将我的订阅者期望的输入从 (Double, Double, Double, Double, Double)
更改为 ((Double, Double, Double), (Double, Double))
,并且编译器给了我一个误导和混淆的错误(关于调度程序的一些东西),直到我想通了发现输入类型错误。
扩展 Leonid 的回答:如果您需要对转换功能的支持,您需要这样的东西:
public func combineLatest<P, Q, R, Y, T>(
_ publisher1: P,
_ publisher2: Q,
_ publisher3: R,
_ publisher4: Y,
_ transform: @escaping (Self.Output, P.Output, Q.Output, R.Output, Y.Output) -> T) ->
AnyPublisher<T, Self.Failure> where
P: Publisher,
Q: Publisher,
R: Publisher,
Y: Publisher,
Self.Failure == P.Failure,
P.Failure == Q.Failure,
Q.Failure == R.Failure,
R.Failure == Y.Failure {
Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4)
.map { tuple, publisher4Value in
transform(tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
}
.eraseToAnyPublisher()
}
我开始尝试使用 SwiftUI,但我遇到了需要 5 个滑块的最新组合的情况。我使用 CombineLatest4
使用 4 个滑块完成所有工作,然后意识到我需要另一个滑块,但没有 CombineLatest5
.
感谢任何帮助。
澄清工作 4 滑块版本:
Publishers
.CombineLatest4($slider1, $slider2, $slider3, $slider4)
.debounce(for: 0.3, scheduler: DispatchQueue.main)
.subscribe(subscriber)
CombineLatest2(CombineLatest3, CombineLatest2)
应该可以解决问题,不是吗?
您可以使用类似的东西:
extension Publisher {
public func combineLatest<P, Q, R, Y>(
_ publisher1: P,
_ publisher2: Q,
_ publisher3: R,
_ publisher4: Y) ->
AnyPublisher<(Self.Output, P.Output, Q.Output, R.Output, Y.Output), Self.Failure> where
P: Publisher,
Q: Publisher,
R: Publisher,
Y: Publisher,
Self.Failure == P.Failure,
P.Failure == Q.Failure,
Q.Failure == R.Failure,
R.Failure == Y.Failure {
Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4).map { tuple, publisher4Value in
(tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
}.eraseToAnyPublisher()
}
}
并这样称呼它:
publisher1.combineLatest(publisher2, publisher3, publisher4, publisher5)
注意 - 从问题中提取的解决方案
好的,弄清楚语法,@Daniel-t 是对的。我只需要创建子发布者:
let paramsOne = Publishers
.CombineLatest3($slider1, $slider2, $slider3)
let paramsTwo = Publishers
.CombineLatest($slider4, $slider5)
paramsOne.combineLatest(paramsTwo)
.debounce(for: 0.3, scheduler: DispatchQueue.main)
.subscribe(subscriber)
请注意,我还必须将我的订阅者期望的输入从 (Double, Double, Double, Double, Double)
更改为 ((Double, Double, Double), (Double, Double))
,并且编译器给了我一个误导和混淆的错误(关于调度程序的一些东西),直到我想通了发现输入类型错误。
扩展 Leonid 的回答:如果您需要对转换功能的支持,您需要这样的东西:
public func combineLatest<P, Q, R, Y, T>(
_ publisher1: P,
_ publisher2: Q,
_ publisher3: R,
_ publisher4: Y,
_ transform: @escaping (Self.Output, P.Output, Q.Output, R.Output, Y.Output) -> T) ->
AnyPublisher<T, Self.Failure> where
P: Publisher,
Q: Publisher,
R: Publisher,
Y: Publisher,
Self.Failure == P.Failure,
P.Failure == Q.Failure,
Q.Failure == R.Failure,
R.Failure == Y.Failure {
Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4)
.map { tuple, publisher4Value in
transform(tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
}
.eraseToAnyPublisher()
}