ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [UIKit, Combine] UIButton Event 구독하기
    카테고리 없음 2023. 9. 20. 01:04
    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)
            }
        }
    }
Designed by Tistory.