Closed brcbydr closed 4 years ago
Hey @brcbydr!
Sure, you can use XCoordinator with storyboards, however it depends on what features you use in these storyboards how much you can benefit from XCoordinator.
Segues
When using segues, you are bound to the prepareForSegue method to set up your destination view controller in your source view controller. This somewhat goes against the principle of the Coordinator Pattern. While it could be realized that these setups are delegated into a coordinator, it may be a lot harder to implement that than simply not using segues at all.
Creating view controllers from Storyboard
As you can see in our Example app, you can use XCoordinator with xibs quite easily. Since Storyboards are quite similar to xib-files, take a look at this documentation for more information on how to create view controllers from storyboards.
Let me know in case this does not fully answer your question, especially in which ways you would like to use XCoordinator in combination to Storyboards.
Hey @pauljohanneskraft, many thanks for your quick support. I didn't use segues like you mentioned. I instantiate viewcontroller using storyboard not nib:
override func prepareTransition(for route: AppRoute) -> NavigationTransition { switch route { case .firstLaunch: let vc: GuideScreenViewController = UIStoryboard(storyboard: .guideScreen).instantiateViewController() let vm = GuideScreenViewModelImpl(router: unownedRouter) vc.bind(to: vm) return .push(viewController) } }
I got that error "Value of type 'GuideScreenViewController' has no member 'bind'". Because viewcontroller has this error "Use of undeclared type 'BindableType'"
import UIKit import RxCocoa import RxSwift class GuideScreenViewController: BindableType { private let disposeBag = DisposeBag() var viewModel: GuideScreenViewModel!
func bindViewModel() {
var page:GuidePage = Bundle.main.loadNibNamed("GuidePage", owner: self, options: nil)?.first as! GuidePage
page.btnGotIt.rx.tap
.bind(to: viewModel.input.gotItTrigger)
.disposed(by: disposeBag)
}
}
I double checked all the implementation but couldn't find the reason. Please let me know if you got my error. Thanks again!
BindableType is defined as a protocol in the Example App itself - if you are using a MVVM approach, you can use it for your project as well, but it might not fit your architecture. If you use a MVC approach, you can simply get rid of the ViewModel completely, then you will also not need to bind a viewModel to your viewController.
I am using MVVM and I think I figure it out. I updated my storyboards. Every storyboard includes just one vc screen and it's name is same as the viewcontroller's name now. Using BindableStoryboardBased instead of BindableType.
protocol BindableStoryboardBased: AnyObject { associatedtype ViewModelType
var viewModel: ViewModelType! { get set }
func bindViewModel()
}
extension BindableStoryboardBased { static var storyboard: UIStoryboard { return UIStoryboard(name: String(describing: self), bundle: Bundle(for: self)) } }
extension BindableStoryboardBased where Self: UIViewController { func bind(to model: Self.ViewModelType) { viewModel = model loadViewIfNeeded() bindViewModel() } static func instantiate() -> Self { guard let vc = storyboard.instantiateInitialViewController() as? Self else { fatalError("The VC of \(sceneStoryboard) is not of class \(self)") } return vc } }
I think we can close the issue. I have another problem and will open new issue for that.
Can I use XCoordinator with the storyboards? I couldn't see any example with storyboard and I have to decide if I can use XCoordinator. Thanks