I’ve got a UIPageViewController with 3 pages. I’m using RxSwift and Cocoa to change the content of each page depending on which page view controller is currently shown.
I have the following property in my UIPageViewController:
var presentationIndex = BehaviorSubject<Int>(value: 0)
Then in viewDidLoad, for each page view controller I do
controllers.forEach { viewController in
let welcomeView = viewController.view.map { $0 as! WelcomeRootView }
welcomeView?.viewModel.subscribe(to: presentationIndex)
}
I emit the index in the following delegate method:
extension PageViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
guard let index = controllers.firstIndex(where: { $0 === pendingViewControllers[0] }) else { return }
presentationIndex.onNext(index)
}
}
My View Model looks like this:
let image = BehaviorSubject<UIImage>(value: PageState.images[0])
let heading = BehaviorSubject<String>(value: PageState.headings[0])
let subheading = BehaviorSubject<String>(value: PageState.subheadings[0])
let isButtonHidden = BehaviorRelay<Bool>(value: true)
func subscribe(to observable: Observable<Int>) {
observable
.share()
.distinctUntilChanged()
.subscribe(onNext: { index in
self.image.onNext(PageState.images[index])
self.heading.onNext(PageState.headings[index])
self.subheading.onNext(PageState.subheadings[index])
if index == 2 {
self.isButtonHidden.accept(false)
} else {
self.isButtonHidden.accept(true)
}
})
.disposed(by: disposeBag)
}
And finally the view:
func bindViewsToViewModel() {
bindImageView()
bindHeadingLabel()
bindSubheadingLabel()
bindButton()
}
func bindImageView() {
viewModel.image
.bind(to: onboardingImageView.rx.image)
.disposed(by: disposeBag)
}
func bindHeadingLabel() {
viewModel.heading
.map { $0 }
.bind(to: headingLabel.rx.text)
.disposed(by: disposeBag)
}
func bindSubheadingLabel() {
viewModel.subheading
.map { $0 }
.bind(to: subheadingLabel.rx.text)
.disposed(by: disposeBag)
}
func bindButton() {
viewModel.isButtonHidden
.bind { self.actionButton.isHidden = $0 }
.disposed(by: disposeBag)
}