skip to Main Content

enter image description here

Above I have a TabBarController with 4 buttons. When I press the second TabBarItem(Cars) or third TabBarItem(Bicycles) I want to pass some values from the firstTabBarItem(HomeScreen) .
I’m using Swift 5 and I don’t have a SceneDelegate in my main project (is a 3 years old project), I have only the AppDelegate and this is why I wasn’t able to try the only example which I found from Stackoverflow about a similar question like mine.
I managed somehow to pass the data between ViewControllers through TabBarController but I don’t think is the right approach anymore (as some people from this community are also saying this on some threads) because when I click on different TabBarItems the data get lost and after is showing up again but with the wrong values etc.
I will attach below a GIF with the bugs which I’m getting while I navigate and also my current code with a link to the DEMO project on GitHub (https://github.com/florentin89/PassDataTabBarController/)

Can you help me please to pass the data using the right implementation ?

Here is my code for HomeScreen ViewController:

import UIKit

class HomeViewController: UIViewController {
    
    @IBOutlet var textfieldHoldingCarsValue: UITextField!
    @IBOutlet var textfieldHoldingBicyclesValue: UITextField!
    
    var valueForCarsScreen = String()
    var valueForBicyclesScreen = String()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        
        valueForCarsScreen = textfieldHoldingCarsValue.text ?? String()
        valueForBicyclesScreen = textfieldHoldingBicyclesValue.text ?? String()
        
        if let navController = self.tabBarController?.viewControllers?[1] as? UINavigationController{
            if let carsTab = navController.children.first as? PostcodeViewController{
                carsTab.receivedValueFromHomeScreen = valueForCarsScreen
            }
        }
        
        if let navController = self.tabBarController?.viewControllers?[2] as? UINavigationController{
            if let bicyclesTab = navController.children.first as? PostcodeViewController{
                bicyclesTab.receivedValueFromHomeScreen = valueForBicyclesScreen
            }
        }
    }
    
    // Logout the user and navigate to Login screen
    @IBAction func logoutTapped(_ sender: UIBarButtonItem) {
        self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
    }
}

Here is my code for the ViewController used for second and third TabBarItem:

import UIKit

class PostcodeViewController: UIViewController {
    
    @IBOutlet var receivedValueLabel: UILabel!
    
    var receivedValueFromHomeScreen = String()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        
        if self.tabBarController?.selectedIndex == 1 {
            receivedValueLabel.text = "Value received for Cars: n" + receivedValueFromHomeScreen
        }

        if self.tabBarController?.selectedIndex == 2 {
            receivedValueLabel.text = "Value received for Bicycles: n" + receivedValueFromHomeScreen
        }
    }
}

Here is a GIF with the bugs/glitches which I’m getting when I navigate between ViewControllers:

enter image description here

Thank you for reading this !

3

Answers


  1. Chosen as BEST ANSWER

    The fix was to move the code of PostcodeViewController from viewWillAppear to viewDidAppear like this:

        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            
            print("Selected index: (self.tabBarController?.selectedIndex ?? -1)")
            
            if self.tabBarController?.selectedIndex == 1 {
                receivedValueLabel.text = "Value received for Cars: n" + receivedValueFromHomeScreen
            }
    
            if self.tabBarController?.selectedIndex == 2 {
                receivedValueLabel.text = "Value received for Bicycles: n" + receivedValueFromHomeScreen
            }
        }
    

    Now everything works perfect !

    GIF below:

    enter image description here


  2. a simple workaround can be.. store data in a static variable in login class, you can access it in other classes.

    long workaround is,

    create a Custom TabBar programmatically, pass data from login viewController to parent CustomTab bar, and pass data to next screen with the help of delegates.

    Login or Signup to reply.
  3. The reason is that viewWillAppear of PostcodeViewController is called before the selectedIndex of your tabbar is changed. The first time it works ok. Just put the line:

    print("selected index = (self.tabBarController?.selectedIndex ?? -1)")
    

    in your viewWillAppear and you will see.

    The easiest way to fix your code is to move the logic of PostcodeViewController from viewWillAppear to viewDidAppear.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search