5
votes

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".

4
By "reuse" do you mean, point the storyboard object to the same class? Or do you mean reuse the exact same view controller instance in memory?Aaron
@Aaron: I don't think pointing to the same VC instance in memory is useful in my case, because in that case each time new tab item selected I have to setup it on each viewDidAppear or something like that. So actually I mean different instances of same class in storyboard. If I create view controller which needs to be reused AND that same view controller has more transitions and relations in storyboard, then I have to duplicate everything. I want to create VC along with its transitions/other VCs and reuse it, not duplicate in storyboard.Pablo
I've updated my question with clarificationPablo
It seems like you are already using container view. So why are not you extending the same approach as I have described in my answer.Ayan Sengupta
@Ayan Sengupta : if there is no better way, then I have to use container approach...Pablo

4 Answers

12
votes

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.

7
votes

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.

0
votes

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).

0
votes

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.