// // UITextView+Publisher.swift // VDS // // Created by Matt Bruce on 5/1/24. // import Foundation import UIKit import Combine extension UITextView { public enum Event { case editingChanged case editingDidBegin case editingDidEnd } public func publisher(for event: Event) -> AnyPublisher { TextViewPublisher(textView: self).publisher(for: event) } } class TextViewPublisher: NSObject, UITextViewDelegate { var textDidChangePublisher: AnyPublisher var didBeginEditingPublisher: AnyPublisher var didEndEditingPublisher: AnyPublisher private var cancellables = Set() init(textView: UITextView) { textDidChangePublisher = NotificationCenter.default.publisher(for: UITextView.textDidChangeNotification, object: textView) .compactMap { notification in (notification.object as? UITextView) } .eraseToAnyPublisher() didBeginEditingPublisher = NotificationCenter.default.publisher(for: UITextView.textDidBeginEditingNotification, object: textView) .compactMap { notification in (notification.object as? UITextView) } .eraseToAnyPublisher() didEndEditingPublisher = NotificationCenter.default.publisher(for: UITextView.textDidEndEditingNotification, object: textView) .compactMap { notification in (notification.object as? UITextView) } .eraseToAnyPublisher() } func publisher(for event: UITextView.Event) -> AnyPublisher { switch event { case .editingChanged: return textDidChangePublisher .map { $0 } .eraseToAnyPublisher() case .editingDidBegin: return didBeginEditingPublisher .map { $0 } .eraseToAnyPublisher() case .editingDidEnd: return didEndEditingPublisher .map { $0 } .eraseToAnyPublisher() } } }