Changing VC issue in Swift. How to pass data between views in tab bar controller?

From your Storyboard diagram, it is clear that you have created a segue from each button in your “tab bar” to another view controller. Except for the unwind segue, segues always create a new instance of the view controller they are switching to. So if you use your setup to switch from view controller 1 to view controller 2 and then back to view controller 1, you won’t be returning to the view controller you came from but instead you will be creating an entirely new view controller 1.

This is why your memory consumption is excessive. You keep creating view controllers until your app crashes.

I would recommend you return to using a tab bar controller. They were designed to allocate the view controllers once up front and then just switch between them. Also, they have a standard look for a reason, it helps the user of your app know immediately how to interact with them.


To pass data between tabs, you won’t use segues because there is no segue happening when you switch tabs. There are many ways you can do this, but they all boil down to having model data stored where all of the tabs can access it. This can be done with CoreData in a larger app. For a simple app, you can do the following:

  1. Create a custom subclass of UITabBarController. Let’s call it CustomTabBarController. Have that class create and hold the model data that will be accessed by each of your tabs.

    CustomTabBarController.swift:

    import UIKit
    
    // This class holds the data for my model.
    class ModelData {
        var name = "Fred"
        var age = 50
    }
    
    class CustomTabBarController: UITabBarController {
    
        // Instantiate the one copy of the model data that will be accessed
        // by all of the tabs.
        var model = ModelData()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
        }
    }
    
  2. In your Storyboard, in the Identity Inspector, change the class of UITabBarController to CustomTabBarController.

    enter image description here

  3. In viewWillAppear in each of your tabs, get a reference to the model data and then you can use it.

    FirstViewController.swift:

    import UIKit
    
    class FirstViewController: UIViewController {
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            // Get a reference to the model data from the custom tab bar controller.
            let model = (self.tabBarController as! CustomTabBarController).model
    
            // Show that we can access and update the model data from the first tab.
            // Let's just increase the age each time this tab appears and assign
            // a random name.
            model.age += 1
    
            let names = ["Larry", "Curly", "Moe"]
            model.name = names[Int(arc4random_uniform(UInt32(names.count)))]
        }
    
    }
    

    SecondViewController.swift:

    import UIKit
    
    class SecondViewController: UIViewController {
        @IBOutlet weak var nameLabel: UILabel!
        @IBOutlet weak var ageLabel: UILabel!
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            // Get a reference to the model data from the custom tab bar controller.
            let model = (self.tabBarController as! CustomTabBarController).model
    
            // This tab will simply access the data and display it when the view
            // appears.
            nameLabel.text = model.name
            ageLabel.text = "\(model.age)"
        }
    }
    

Leave a Comment