Chapter 3. Binder. - dmsl1805/Cookbook GitHub Wiki
Here is a definition of ViewControllerBinder protocol. It is so common to touch the view of the view controller inside of the “viewDidLoad”. There are rare cases where we use a different approach, but the current one suits 99% of the time.
import RxSwift
protocol ViewControllerBinder: Disposable {
associatedtype DisposeViewControllerContainer: UIViewController, DisposeContainer
var viewController: DisposeViewControllerContainer { get }
func bindLoaded()
}
import RxViewController
extension ViewControllerBinder where Self: AnyObject {
func bind() {
viewController.rx.viewDidLoad
.subscribe(onNext: unowned(self, in: Self.bindLoaded))
.disposed(by: viewController.bag)
}
}
And how actual logic can be implemented.
import Foundation
import Nuke
final class MovieDetailBinder: ViewControllerBinder {
unowned let viewController: MovieDetailViewController
private let driver: MovieDetailDriving
init(viewController: MovieDetailViewController,
driver: MovieDetailDriving) {
self.viewController = viewController
self.driver = driver
bind()
}
func dispose() { }
func bindLoaded() {
// 1. Style
viewController.statusBarStyle = .lightContent
// 2. State
viewController.bag.insert(
viewController.rx.viewWillAppear
.bind(onNext: unowned(self, in: MovieDetailBinder.viewWillAppear)),
driver.data
.drive(onNext: unowned(self, in: MovieDetailBinder.configure))
)
// 3. Action
viewController.bag.insert(
viewController.backButton.rx.tap
.bind(onNext: driver.close)
)
}
private func viewWillAppear(_ animated: Bool) {
viewController.navigationController?.setNavigationBarHidden(true, animated: animated)
}
private func configure(_ data: MovieDetailData) {
viewController.headerView.configure(with: data)
viewController.tipsView.configure(with: data)
if let url = data.posterUrl {
Nuke.loadImage(with: URL(string: url)!, into: viewController.posterImageView)
}
}
}
Here is what this binder does:
- Apply some static style properties
- Bind state changes from Driver to View
- Bind actions from View to Driver
Want even more separation of UI logic? Look further.