Pablo
Pablo

Reputation: 29519

Reusing UIViewController for two Tab bar items

I have 1 tab bar controller in storyboard and 1 UIViewController associated with it. I would like to re-use the same UIViewController in order to create second item in tab bar. When I am creating second relation from tab bar to view controller I need to specify 2 different items names. How can I re-use same view controller and set different items names from storyboard? If not possible to do it in storyboard, then do I have to rename each in tab bar controller class or there is better way?

I was going to provide different data to view controller in prepareforsegue.

UPDATE:

little more details and clarification

enter image description here

In above screenshot marked VC at the moment is reachable a) directly from tab, b) through 3 transitions. I want to add another DIRECT relation to initial tab bar, just like in case of "a".

Upvotes: 5

Views: 4491

Answers (4)

gutaker
gutaker

Reputation: 181

I've found much simpler solution using storyboard only.

Setup your storyboard like this:

Storyboard

Then in your Navigation Controller Identity Inspector set Restoration ID like this:

enter image description here

And in your ViewController class file put the following code:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.navigationItem.title = parent?.restorationIdentifier
    label.text = parent?.restorationIdentifier
}

or do what you like based on parent?.restorationIdentifier value

If you don't want the Navigation TopBar to appear on the ViewController just set it to None in Attributes Inspector of the desired Navigation Controller like this:

enter image description here

That's it! Hope it helps.

Upvotes: 7

ysnzlcn
ysnzlcn

Reputation: 618

I needed slightly different solution than the accepted answer. I needed to use same Table View Controller with the different data source for different tab bar items. So in the storyboard, i created two Navigation Controllers with same classes like this; enter image description here

I also give different "Restoration ID" to each of them.

For the first one, I gave "navCont1" and "navCont2" for the second one. enter image description here

In subclass("GeneralNavCont") of these Navigation Controllers; I override init method and check restoration id of self. Then i initiate my TableViewController and set its data source based on ids like this;

class GeneralNavCont: UINavigationController {

   var dataSource1 = [Countries]()
   var dataSource2 = [Cities]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

     required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            initiateTableVCBasedOnId()
        }

      func initiateTableVCBasedOnId() {
            let storyBoard = UIStoryboard(name: "Main", bundle: nil)
            let tableVC = storyBoard.instantiateViewController(withIdentifier: "tableVC") as! MyTableViewController

            if self.restorationIdentifier == "navCont1" {
                tableVC.dataSource = self.dataSource1
                self.viewControllers = [tableVC]
            }
            else if self.restorationIdentifier == "navCont2" {
                tableVC.dataSource = self.dataSource2
                self.viewControllers = [tableVC]
            }

        }
}

Hope it helps someone. Cheers.

Upvotes: 0

Raja Rao
Raja Rao

Reputation: 5865

Yes you can. All you need to do is to create a new View Controller in StoryBoard as if there is going to be a different View Controller for tab 2. Then Select the 2nd view controller and simply add its class name the same classname of view controller 1

Things to note: When you are sharing the same view controller class (.m ad .h) files, each tab will create a NEW instance of that class.

Edit: This works as long as you have either a "custom" cell scenario (i.e. reusing two table view controllers) OR, have all your views inside a "container view" (i.e. reusing UIView).

Upvotes: 0

Ayan Sengupta
Ayan Sengupta

Reputation: 5386

I can give you a little tweak for that and at least that worked for me.

  1. Drag a tabbarcontroller and associated tab item view controllers to your storyboard. Name them as you like.
  2. Create an extra view controller that you want to reuse from your storyboard.
  3. Add container views to each tab item view controllers and remove their default embedded view controllers.
  4. Create embed segue from each tab item controller to your re-usuable view controller.

The configuration looks something like the following:

Screenshot

Thus you can use the same embedded VC for different tabbar item. Obviously if you need the reference of the tabbarcontroller, you need to use self.parentViewController.tabBarController instead of self.tabBarController directly. But it solves the issue of reusing a VC right from the storyboard.

Upvotes: 12

Related Questions