1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- //
- // UIControl.swift
- // Mastodon
- //
- // Created by sxiaojian on 2021/3/8.
- //
- import Foundation
- import UIKit
- import Combine
- /// A custom subscription to capture UIControl target events.
- final class UIControlSubscription<SubscriberType: Subscriber, Control: UIControl>: Subscription where SubscriberType.Input == Control {
- private var subscriber: SubscriberType?
- private let control: Control
- init(subscriber: SubscriberType, control: Control, event: UIControl.Event) {
- self.subscriber = subscriber
- self.control = control
- control.addTarget(self, action: #selector(eventHandler), for: event)
- }
- func request(_ demand: Subscribers.Demand) {
- // We do nothing here as we only want to send events when they occur.
- // See, for more info: https://developer.apple.com/documentation/combine/subscribers/demand
- }
- func cancel() {
- subscriber = nil
- }
- @objc private func eventHandler() {
- _ = subscriber?.receive(control)
- }
- }
- /// A custom `Publisher` to work with our custom `UIControlSubscription`.
- struct UIControlPublisher<Control: UIControl>: Publisher {
- typealias Output = Control
- typealias Failure = Never
- let control: Control
- let controlEvents: UIControl.Event
- init(control: Control, events: UIControl.Event) {
- self.control = control
- self.controlEvents = events
- }
-
- func receive<S>(subscriber: S) where S : Subscriber, S.Failure == UIControlPublisher.Failure, S.Input == UIControlPublisher.Output {
- let subscription = UIControlSubscription(subscriber: subscriber, control: control, event: controlEvents)
- subscriber.receive(subscription: subscription)
- }
- }
- /// Extending the `UIControl` types to be able to produce a `UIControl.Event` publisher.
- protocol CombineCompatible { }
- extension UIControl: CombineCompatible { }
- extension CombineCompatible where Self: UIControl {
- func publisher(for events: UIControl.Event) -> UIControlPublisher<UIControl> {
- return UIControlPublisher(control: self, events: events)
- }
- }
|