How to pass data between viewcontrollers in tabbed applications? - ios

I have found 2 methods but am wondering if there's a better solution with xcode 5.
How to Pass Data Between iOS Tab bar Using Protocol and delegate
Xcode: Storyboard Tabbed Application Passing Data Back and Forth
Tried printing a NSLog in prepareForSegue but it doesn't even get called?
What is the current best practice to pass data between viewcontrollers for tabbed applications using storyboard and with io6 support?

Have a look at this question: iPhone: How to Pass Data Between Several Viewcontrollers in a Tabbar App
Also the imho cleanest way is to use the NSNotificationcenter. It's simple: How to use NSNotificationcenter

singleton is a good idea. You can also do it by using AppDelegate. If your data is not huge you can store your data in AppDelegate and access those from any viewcontroller.

I have used delegate approach from 1. I wanted to pass data between third and second view controller so I just added this into third view controller viewDidLoad to catch if user goes to third tab after the tab bar starts in the first view controller
SecondViewController *svc = [self.tabBarController.viewControllers objectAtIndex:1];
self.delegate = svc;

Related

How to find Instance of View Controller made by storyboard

I am trying to make a tabbed application in Xcode that allows the user to take a photo and edit it on the FirstViewController class and when they are done display it on the SecondViewController.
When I started the project, Xcode automatically made the two viewControllers for me in the storyboard. What I need now is to find the instance of the second viewController that was generated so I can call a method and pass an argument (the UIImage) from the first view controller to the second like this.
FirstViewContoller.m
-(void) passImageToSecondVC (UIImage *) img
{
[<instanceOf_SecondViewController> receiveImg: img];
}
SecondViewContoller.m
-(void) receiveImage (UIImage *) img
{
//Code to display the image received
}
What Im asking is how can I find the name of the instance of the SecondViewController (shown by <> in the example code) generated by Xcode so I can call this method.
Although I'm very close to just doing this programmatically which I find much easier I wanna learn how to do this through the storyboard also I'm very open to hear other solutions to this problem. Thank you!
There's no way to do this through the storyboard. You don't access the view controller by its name. Each view controller has access to the tab bar controller through self.tabBarController. You can access individual controllers from the tab bar controller's viewControllers array. So, to get a reference to the controller in the second tab, you would use self.tabBarController.viewControllers[1].
Use delegates pattern.
Make one vc be a delegate of the other vc and communicate data between them. I think It's a common scenario.
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html

Sending data between ViewControllers without segues

Is there a way to send data between ViewControllers without using segues?
Specifically I have two ViewControllers embedded in a TabBarViewController. One is called PlayingCardViewController and the other is called HighScoreViewController. I want to pass a class HighScore from PlayingCardViewController to HighScoreViewController. I want to transfer the data from PlayingCardViewController as soon as I press the redeal button in PlayingCardViewController but I don't want to transition to the HighScoreViewController as that would be jarring for the player.
I thought about using segues and holding the HighScores in an array and passing that to all the VC's that PlayingCardViewController is connected to but I realized that that seems overly complicated and there must be a simpler way to pass the data upon hitting the redeal button.
Some relevant links
Passing Data between View Controllers
I'm just going to do this with bullet points:
You could implement a custom tab bar controller (your own UITabBarController subclass), and use this instead of a basic UITabBarController.
Your PlayingCardViewController could have its own delegate protocol/property.
The delegate protocol could define a method like playingCardVC:didSetHighScore:.
Your tab bar controller would be the PlayingCardViewController's delegate.
The tab bar controller could keep a reference to the HighScoreViewController.
When your tab bar controller gets the playingCardVC:didSetHighScore:, it could pass whatever you want to your HighScoreViewController.

iOS: Sharing state/properties between 3 controllers

I have a form and it gives users an advance mode. I've already googled and looked around at different SO questions (sharing data between controllers, protocols, and passing data between segues) but I'm wondering if there's a better way.
Is there a way for me to have some sort of "master controller" that holds all the data while going back and forth between 3 different controllers?
If I can just hold the data for the second controller and allow my user to make that quick advance edit in the third while keeping it's data intact, that'll do for now.
Thanks in advance
Here's a quick walkthrough of my app:
FirstViewController: User selects an option
SecondViewController: User does some editing while storing that option
(*Optional)ThirdViewControl: User one more quick edit using a web view
*xcode5/iOS7
If you are passing data from one view controller to the next and you are using segues, then call a method on the next view controller in line from prepareForSegue. For example, when segueing between ViewController1 and ViewController2, add this code to ViewController1 and repeat as necessary in other view controllers:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ViewController2 *viewController = segue.destinationViewController;
[viewController configureWithSomeState:self.someState];
}
This code assumes that someState is a property defined on ViewController1.
EDIT: One thing you could do--although I do not like this approach because it forces your VCs to have special knowledge about their parent controller--is to derive UINavigationController, then in your storyboard, use the new class for your navigation controller. Store the state in the derived navigation controller and access it from each VC like this:
DerivedNavigationController *navigationController = (DerivedNavigationController *)self.navigationController;
navigationController.someState...;
Typically I'd put information that is used throughout the application in the application delegate where everybody has access to it.
Another possibility is to implement a singleton data management class to hold it for you.
In this case it seems like the application is really a pretty linear flow, so I'd just pass the selection from vc1 to vc2 and then again to vc3 in the respective prepareForSegue calls.

Using a UINavigationController for a set path without Back options

I am using a UINavigationController within my app (as expected) for a specific path the user takes when taking a turn in my turn based game.
When they move through the turn controllers they do not actually have the option to go Back from the Navigation Controller. This is planned/expected behaviour.
My question is, is it best to keep the other controllers on the UINavigationController stack when they are not going to be used again.
Should they be de-alloced immediately, or wait for the whole turn to be complete and let them go when the navigation controller goes (how it is at the moment). Some of the controllers hold data/images etc as properties so I am wondering if it would be more efficient to get rid of these on the fly?
If it is, what is the best method to load new controllers into the UINavigationController at present I am using self performSegue... or buttons that push to the VC from the storyboard setup.
You can manipulate navigation controller viewControllers using this code
NSMutableArray *viewControllers = self.navController.viewControllers;
//remove or add in the array
[self.navController setViewControllers:viewControllers];

How to handle click events in UISplitView nested controllers

I'm Monotouch for iOS development.
I've got a SplitView for iPad and the main view controller is UITabBar with UINavigation inside and UITableView nested in it. Thats a quite complicated controllers chain. And I need to handle row click event in TableView and return it back up to UISplitView to make an appropriate action on DetailView controller.
Is it a good design to define an event in each controller in the controllers chain and transit the event from the very end to the very begining calling the intermediate events?
I would recommend to keep things simple. Usually the splitViewController is a property of the AppDelegate (if not, you can just add one). So you can access the splitViewController from anywhere in your app by calling
[[[[UIApplication sharedApplication] delegate] splitViewController] anyMethodYouWantToCallOnTheSplitVC];
#Tobi was on the right track, you can get access your AppDelegate using var myApp = UIApplication.SharedApplication.Delegate as AppDelegate; and at that point either reference the public instance of your UISplitViewController or call a public method from myApp.

Resources