import Combine
import UIKit
class ViewController: UIViewController {
let viewModel: ViewModel
var cancellable = Set<AnyCancellable>()
let uiButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
func bind() {
uiButton.tapPublisher
.receive(on: RunLoop.main)
.sink { [weak self] in
self?.viewModel.didTapButton()
}.store(in: &cancellable)
}
}
extension UIButton {
var tapPublisher: AnyPublisher<Void, Never> {
controlPublisher(for: .touchUpInside)
.map { _ in }
.eraseToAnyPublisher()
}
}
import Combine
import UIKit
extension UIControl {
func controlPublisher(for event: UIControl.Event) -> UIControl.EventPublisher {
.init(control: self, event: event)
}
struct EventPublisher: Publisher {
typealias Output = UIControl
typealias Failure = Never
let control: UIControl
let event: UIControl.Event
func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, UIControl == S.Input {
let subscription = EventSubscription(control: control, subscrier: subscriber, event: event)
subscriber.receive(subscription: subscription)
}
}
fileprivate class EventSubscription<EventSubscriber: Subscriber>: Subscription where EventSubscriber.Input == UIControl, EventSubscriber.Failure == Never {
let control: UIControl
let event: UIControl.Event
var subscriber: EventSubscriber?
init(control: UIControl, subscrier: EventSubscriber, event: UIControl.Event) {
self.control = control
self.subscriber = subscrier
self.event = event
control.addTarget(self, action: #selector(handleEvent), for: event)
}
func request(_ demand: Subscribers.Demand) {}
func cancel() {
subscriber = nil
control.removeTarget(self, action: #selector(handleEvent), for: event)
}
@objc func handleEvent() {
_ = subscriber?.receive(control)
}
}
}