Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How a UITabBarController fit into the VIPER architecture?

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.

like image 451
Tibor Molnár Avatar asked May 13 '15 13:05

Tibor Molnár


3 Answers

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.

like image 198
Maddiee Avatar answered Sep 27 '22 17:09

Maddiee


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()
like image 22
Sei Flavius Avatar answered Sep 25 '22 17:09

Sei Flavius


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.

like image 25
bennythemink Avatar answered Sep 25 '22 17:09

bennythemink