Closed snowtema closed 3 years ago
Hi @snowtema
you can build and integrate you Uitabbarcontroller the way you like. You can build it even manually and set it as a rootViewController of your view. Routcomposer just sits outside of your app structure and when you need to navigate somewhere it will update the graph of your view controllers according to the configuration you passed to the navigate method.
@snowtema One of the way can be:
let tabBarFactory = CompleteFactoryAssembly(factory: TabBarControllerFactory())
.with(ClassFactory<HomeViewController, Any?>(), using: UITabBarController.add())
.with(ClassFactory<AccountViewController, Any?>(), using: UITabBarController.add())
.assemble()
// applicationDidFinishLaunching
let tabBarController = tabBarFactory.build()
window.rootViewController = tabBatController
window.makeKeyAndVisible()
// Later
let tabScreenConfiguration = SingleContainerStep(
finder: ClassFinder(),
factory: tabBarFactory)
.using(GeneralAction.replaceRoot())
.from(GeneralStep.root())
.assemble()
router.commitNavigation(to: tabScreenConfiguration, with: nil, completion: nil)
You can reuse this factory in the routing configuration later. See advanced examples here
@snowtema please let me know what is confusing you
@snowtema Closing due to inactivity. Feel free to reopen if you'll have any questions.
Hi, @ekazaev I tried code from your link (examples) and got this:
My tab bar configuration:
var tabBarScreen: DestinationStep<UITabBarController, Any?> {
StepAssembly(
finder: ClassFinder<UITabBarController, Any?>(options: .current, startingPoint: .root),
factory: CompleteFactoryAssembly(factory: TabBarControllerFactory())
.with(ClassFactory<TodayViewController, Any?>(), using: UITabBarController.add())
.with(ClassFactory<ProfileViewController, Any?>(), using: UITabBarController.add())
.assemble())
.using(GeneralAction.replaceRoot())
.from(GeneralStep.root())
.assemble()
}
On another screen (Splash) I call router.commitNavigation(to: ConfigurationHolder.configuration.tabBarScreen, animated: true, completion: nil)
and tab bar items were set in view controller's viewDidLoad
, and that's why I didn't see the Second tab while I don't click on it. The question is how I can configure the tab bar controller (tab names, etc) before display it?
@snowtema That is the expected behaviour of viewDidLoad
. The second view was not loaded, because it is not necessary until user actually switches to this tab. It is default and expected behaviour of the UITabBarController
. You need to set up your title and tab bar items either in init method of the view controller or in the custom factory for your view controller. You can try to use the configuration: ((_: VC) -> Void)? = nil
block of ClassFactory
. But i would suggest you to create custom factories and setup everything there. You'll benefint from that in future.
Okay, thanks. I'll try this.
Also, I found in TabBarControllerFactory
initializer configuration
param. Can I use it for this?
You can, but then you are bringing knowledge of what is inside of tab bar to the tab bar factory, which kinda breaks encapsulation principle. But you can use it for the configuration of the UITabBarController
itself.
I'm trying to move from RxFlow to a better solution and found yours. At first sight, it looks more complex but more configurable :) Anyway, many thanks!
Btw, factory solution works great )
@snowtema Happy to hear. Please don't hesitate to ask any questions you may have regarding the library
Hi again! @ekazaev
I wanted to display a tab view controller with two tabs (Today and Account), and the account should lay down in the navigation controller?
How I can change my configuration to support Navigation in Account vc?
var tabBarScreen: DestinationStep<UITabBarController, Any?> {
StepAssembly(
finder: ClassFinder<UITabBarController, Any?>(options: .current, startingPoint: .root),
factory: CompleteFactoryAssembly(factory: TabBarControllerFactory())
.with(TodayFactory(), using: UITabBarController.add())
.with(AccountFactory(), using: UITabBarController.add())
.assemble())
.using(GeneralAction.replaceRoot())
.from(GeneralStep.root())
.assemble()
}
Hi @snowtema
if you are using composable factory aproach then just replace AccountFactory with another CompleteFactoryAssembly that will create a navigation controller with the Account factory inside
Example from one of the tests:
let container = CompleteFactoryAssembly(factory: TabBarControllerFactory<UITabBarController, Any?>())
.with(ClassFactory<UIViewController, Any?>())
.adding(contextTask1)
.adding(contextTask2)
.with(ClassFactory<UIViewController, Any?>(), using: UITabBarController.add())
.with(CompleteFactoryAssembly(factory: TabBarControllerFactory<UITabBarController, Any?>())
.with(ClassFactory<UIViewController, Any?>()
).assemble(),
using: UITabBarController.add(at: 1, replacing: true))
.adding(contextTask3)
.with(CompleteFactoryAssembly(factory: NavigationControllerFactory<UINavigationController, Any?>())
.with(CompleteFactoryAssembly(factory: TabBarControllerFactory<UITabBarController, Any?>())
.with(ClassFactory<UIViewController, Any?>()
).assemble()
).assemble())
.assemble()
@snowtema I added a CompleteFactoryAssembly
example for you. Please check InternalSearchConfiguration
in the Example in the latest master.
Thanks, will try this
It works, many thanks.
@snowtema You are welcome.
Hi,
What if I want to create a TabBar application and don't want to use Storyboards. How can I assemble configuration?