public var tap: ControlEvent

extension Reactive where Base: UIButton {

    

    /// Reactive wrapper for `TouchUpInside` control event.

    public var tap: ControlEvent<Void> {

        return controlEvent(.touchUpInside)

    }

}

 

extension Reactive where Base: UIControl {

 

    public func controlEvent(_ controlEvents: UIControlEvents) -> ControlEvent<()> {

        let source: Observable<Void> = Observable.create { [weak control = self.base] observer in

                MainScheduler.ensureExecutingOnScheduler()

 

                guard let control = control else {

                    observer.on(.completed)

                    return Disposables.create()

                }

 

                let controlTarget = ControlTarget(control: control, controlEvents: controlEvents) {

                    control in

                    observer.on(.next(()))

                }

 

                return Disposables.create(with: controlTarget.dispose)

            }

            .takeUntil(deallocated)

 

        return ControlEvent(events: source)

    }

}

 

final class ControlTarget: RxTarget {

    typealias Callback = (Control) -> Void

 

    let selector: Selector = #selector(ControlTarget.eventHandler(_:))

 

    weak var control: Control?

#if os(iOS) || os(tvOS)

    let controlEvents: UIControlEvents

#endif

    var callback: Callback?

    #if os(iOS) || os(tvOS)

    init(control: Control, controlEvents: UIControlEvents, callback: @escaping Callback) {

        MainScheduler.ensureExecutingOnScheduler()

 

        self.control = control

        self.controlEvents = controlEvents

        self.callback = callback

 

        super.init()

 

        control.addTarget(self, action: selector, for: controlEvents)

 

        let method = self.method(for: selector)

        if method == nil {

            rxFatalError("Can't find method")

        }

    }

#elseif os(macOS)

    init(control: Control, callback: @escaping Callback) {

        MainScheduler.ensureExecutingOnScheduler()

 

        self.control = control

        self.callback = callback

 

        super.init()

 

        control.target = self

        control.action = selector

 

        let method = self.method(for: selector)

        if method == nil {

            rxFatalError("Can't find method")

        }

    }

#endif

 

    @objc func eventHandler(_ sender: Control!) {

        if let callback = self.callback, let control = self.control {

            callback(control)

        }

    }

 

    override func dispose() {

        super.dispose()

#if os(iOS) || os(tvOS)

        self.control?.removeTarget(self, action: self.selector, for: self.controlEvents)

#elseif os(macOS)

        self.control?.target = nil

        self.control?.action = nil

#endif

        self.callback = nil

    }

}

 

public struct ControlEvent<PropertyType> : ControlEventType {

    public typealias E = PropertyType

 

    let _events: Observable<PropertyType>

 

    /// Initializes control event with a observable sequence that represents events.

    ///

    /// - parameter events: Observable sequence that represents events.

    /// - returns: Control event created with a observable sequence of events.

    public init<Ev: ObservableType>(events: Ev) where Ev.E == E {

        _events = events.subscribeOn(ConcurrentMainScheduler.instance)

    }

}

posted @ 2018-05-09 20:59  zzfx  阅读(137)  评论(0编辑  收藏  举报