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
:
Thank you for reading this !
3
Answers
The fix was to move the code of
PostcodeViewController
fromviewWillAppear
toviewDidAppear
like this:Now everything works perfect !
GIF below:
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.
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:
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.