How a UITabBarController fit into the VIPER architecture?
Asked Answered
F

3

17

I am writing an application which has a TabBar based navigation. I am adopting the VIPER architecture but I am really confused with the topic of how a UITabBarController's tab changing should be implemented.

Frictional answered 13/5, 2015 at 13:21 Comment(0)
P
17

This might be late, but it might be helpful for others. My use case was to implement the tabBarController after the login screen. There can be many ways we can do it in VIPER but how I did it is as follows:

  1. Allocated TabBar manually, without using storyboards.
  2. Create a new WireFrame class only for TabBarWireframe presentation.
  3. Create a singleton class with one mutable array which will contain all the view controllers to be assigned to the tabBarController.
  4. Create a json file which will provide me the values of tabs, This step can be skipped as I wanted tabs to be dynamic based on value from JSON file. If u have static tabs skip this step.
  5. In TabBarWireframe, put a loop which call all your tabs wireframes.
  6. In your individual wireframes just instantiate the viewController obj and add it to the singleton class array we created in step 3.
  7. After all viewController which are part of tabs are part of the array. Just present the tabBar Controller from the loginviewcontroller instance(Its instance just pass through a method to the tabBarWireframe class).

Hope I made sense.

Prem answered 4/9, 2015 at 19:25 Comment(3)
I did almost the same, but plus 1 for the explanationMillwater
ohh...great to hear :)Prem
but how it is following viper? also in my case I need to make some network call on rootviewcontroller level which also has to host tabbarAdios
S
7

Another way to implement UITabBarController with VIPER architecture is to provide a TabBarInterface

import Foundation
import UIKit

protocol TabBarInterface {
    func configuredViewController() -> UIViewController
}

So that each wireframe that presents a view controller in the tab bar controller implements TabBarInterface and then installIntoWindow just loops through all the wireframes calling configuredViewController for each wireframe it will present.

import Foundation

import UIKit

class TabBarWireframe : NSObject {

    let wireFrames:[TabBarInterface]
    var rootWireframe : RootWireframe?

    init(_ wireFrames:TabBarInterface...) {
        self.wireFrames = wireFrames
        super.init()
    }

    private override init() {
        self.wireFrames = [TabBarInterface]()
    }

    func installIntoWindow(window: UIWindow) {
        let tabBarController = MainTabBarController()

        var viewControllers = [UIViewController]()

        for wireFrame in wireFrames {
            viewControllers.append(wireFrame.configuredViewController())
        }

        tabBarController.viewControllers = viewControllers
        tabBarController.navigationItem.title = "Visva"

        self.rootWireframe?.installTabBarControllerIntoWindow(tabBarController: tabBarController, window: window)
    }

}

Please note that in our case RootWireframe installs the tab bar controller into the main Window, i.e:

window.rootViewController = tabBarController
window.makeKeyAndVisible()
Snorter answered 7/6, 2016 at 22:22 Comment(1)
Could I get this as a code template example on Github or something?Checky
M
2

I'm still new to VIPER so my two cents may not be worth much but maybe have the tabbar as a private property on the AppDelegate. When you need to change to a particular index have utility methods that change the tabbar selected index but also trigger the wireframe/router creation process.

Millipede answered 19/5, 2015 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.