如何将信号阵列合并为单个Signal ReactiveCocoa 4

nbu*_*urk 2 ios reactive-cocoa swift

在我的设置中,我有一个GridView由许多GridViewCells 组成的.每个细胞都有一个UITapGestureRecognizer.

为方便起见,它GridView具有以下函数func cellsTapGestureRecognizers() -> [UITapGestureRecognizer?] ,该函数 返回其UITapGestureRecognizer所有单元格的s(如果存在).

UIViewController使用中GridView,我的目标是将水龙头视为Signals.我设法做到这一点,但有限制,我Signal为每个创建一个GridViewCell似乎不必要的.

func createTapSignals() -> [Signal<Position, NoError>?] {
    var signals: [Signal<Position, NoError>] = []
    for maybeTap in self.gridView.cellsTapGestureRecognizers() {
        if let tap = maybeTap {
            let signal = tap.gestureSignalView()
                .map { $0 as! GridViewCell }
                .map {$0.position}
            signals.append(signal)
        }
    }
    return signals
}
Run Code Online (Sandbox Code Playgroud)

是否有可能合并所有创建的信号,createTapSignals()最终只剩下一个类型的信号Signal<Position, NoError>

我查看了文档,但只找到了如何SignalProducers通过使用合并的方式flatten(.Merge).是否有类似的做法,我可以采取合并的ArraySignal秒.

请注意,gestureSignalView()这是在函数中使用上述返回Signal<UIView, NoError>携带UIViewUITapGestureRecognizer(由@ NachoSoto的启发要旨).

nbu*_*urk 8

RAC Github回购中搜索后,我自己找到了解决方案.

(静态)功能merge正是我正在寻找的.它是SignalType协议的一部分(Signal符合)并在协议扩展中实现.

所以,我可以做以下事情:

let signals = createTapSignals()
let mergedSignal = Signal.merge(signals)
Run Code Online (Sandbox Code Playgroud)

供参考,以下是如何merge实现:

public static func merge<S: SequenceType where S.Generator.Element == Signal<Value, Error>>(signals: S) -> Signal<Value, Error> {
    let producer = SignalProducer<Signal<Value, Error>, Error>(values: signals)
    var result: Signal<Value, Error>!

    producer.startWithSignal { (signal, _) in
        result = signal.flatten(.Merge)
    }

    return result
}
Run Code Online (Sandbox Code Playgroud)