Skip to content

Instantly share code, notes, and snippets.

@leviathan
Created January 7, 2021 16:46
Show Gist options
  • Save leviathan/95f3ad0dfca8470400c9815b42acd2cc to your computer and use it in GitHub Desktop.
Save leviathan/95f3ad0dfca8470400c9815b42acd2cc to your computer and use it in GitHub Desktop.
ObservableViewController - functional reactive View Lifecycle handling with Combine
import Combine
import UIKit
/// View controller, that publishes events for it's `view`'s lifecycle,
/// and allows type safe access to it's main `UIView`.
class ObservableViewController<V: UIView>: UIViewController {
typealias LifecycleEvent = (view: V, animated: Bool)
/// Broadcasts event after the controller's view is loaded, e.g. `viewDidLoad()`.
var onViewDidLoad: AnyPublisher<Void, Never> {
onViewDidLoadPublisher.eraseToAnyPublisher()
}
/// Broadcasts events when the controller's view was added to a view hierarchy, e.g. `viewDidAppear(...)`.
var onDidAppear: AnyPublisher<LifecycleEvent, Never> {
onDidAppearPublisher.eraseToAnyPublisher()
}
private lazy var onViewDidLoadPublisher = PassthroughSubject<Void, Never>()
private lazy var onDidAppearPublisher = PassthroughSubject<LifecycleEvent, Never>()
/// Type safe access to the controller's main `UIView`.
lazy var contentView: V = V()
override func loadView() {
view = contentView
}
override func viewDidLoad() {
super.viewDidLoad()
onViewDidLoadPublisher.send()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
onDidAppearPublisher.send((contentView, animated))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment