transfer several variables to another ViewController - ios

Tell me, please, how should i transfer several variables from one ViewController to another?
For example, i have
ViewControlle.m
- (void) transferVar{
int a = 10;
int b = 11;
}
and i want to transfer them to another ViewController (SecondViewController.m). What should i do?

you can add a property on the second view controller for every variable you want to pass (or an array to contain them all), then if you are making the segue on the storyboard use the method
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
and inside it make this
SecondViewController *svc = (SecondViewController *) segue.destinationViewController;
There you have the view controller you want to pass values so only save it
svc.yourArray = #[[NSNumber numberWithInt:a],[NSNumber numberWithInt:b]];
Also it is highly recommendable to add a segue identifier to the storyboard segue and check
if([segue.identifier isEqualToString: #"theIdentifier"])
to be sure it is the segue that you wanted
Now on the viewDidLoadMethod you can use them.
If you are not using the storyboard segue just assign the value after initiating the view.

Related

Need some insight to make a 3 UIButton menu in XCode that toggles and changes dataset in the main ViewController

I'm new on Stackoverflow and I'm currently learning XCode from scratch and I'm in a process of making a Single Page Application with options.
Anyone knows how to efficiently make a simple menu with multiple selectable UIButtons that make the main ViewController display different datasets depending on the selection in XCode?
Tried different things (creating SecondViewController for example but can't figure out how to pass data from it to main ViewController).
Any help will be greatly appreciated.
Refer this:
https://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
How to pass prepareForSegue: an object
Simple Test from above Answer Reference:
Simply grab a reference to the target view controller in prepareForSegue: method and pass any objects you need to there. Here's an example...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
REVISION: You can also use performSegueWithIdentifier:sender: method to activate the transition to a new view based on a selection or button press.
For instance, consider I had two view controllers. The first contains three buttons and the second needs to know which of those buttons has been pressed before the transition. You could wire the buttons up to an IBAction in your code which uses performSegueWithIdentifier: method, like this...
//When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"MySegue"]) {
// Get destination view
SecondView *vc = [segue destinationViewController];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}
Hope this help but please go through refernces!

send an array to next view controller

In my app, I have 4 view controllers, (login,welcome,game view and results view). In the game view, I have two additional views (like this)[screen shot link to the views]. I am using a web api to get data, and my data is consist of items(each item has 1 image and 4 string). Item number is not constant so based on the amount of items(which I store it inside an array), I transition my views from one to another until I ran out of items.(The way I present is really similar to view transitions sample from apple. After displaying the last item, I use perform segue to go to next view.
The problem that I am trying to solve
I am trying to create an additional view/ or view controller that uses some part of the information from my items array.
my question
Why I am getting null for container views array ?(_results array is the array that has the items)
this is what I tried:
based on this question:
GameView
ContainerViewController *container = [[ContainerViewController alloc]init];
container.array = _results;
[self performSegueWithIdentifier:#"changetoResults" sender:self];
ContainerViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"items in the array - containerviewcontroller.m %#",array);
}
this is the console:
2013-11-26 19:11:29.157 GuessTheImage[3664:70b] there are 8 , of items in the current index -gameviewcontroller.m
2013-11-26 19:12:44.439 GuessTheImage[3664:70b] items in the array - containerviewcontroller.m (null)
Thank you.
Because the ViewController that you create isn't the ViewController that you go to via the segue.
If you'd like to use a segue, you can get the destination ViewController (it already exists) in a prepareForSegue method and tune it however you want (in your case - add an array).
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"changetoResults"])
{
ContainerViewController *vc = (ContainerViewController *)[segue destinationViewController];
vc.array = _results;
}
}
There are two things that you are not doing correctly:
You are setting the array on a temporary view controller different from the instance activated by your segue, and
You are logging the array too early: viewDidLoad: is called before the segue code manages to put the array into the new view controller.
To fix the first problem, remove the two lines above the "perform segue" call, and add this method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"changetoResults"]) {
ContainerViewController *container = segue.destinationViewController;
container.array = _results;
}
}
To fix the second problem, move the logging code into the viewDidAppear:. NSLog should start showing the correct number of items.

Objective C Segue identity

I have a pretty simple question. Say you have 2 view controllers A and B. A is a UITableView with STATIC CELLS. That is A is built using storyboard objects only as opposed to programmatically. B is also a UITableView but built programmatically with DYNAMIC CELLS. So I wired up Segues (with identifiers set in the storyboard) from each cells in A to the B Tableview.
Now what I would like to have is to know which segue has been pushed when a row in A is selected. I know this can easily be done if I create the cells in view A programmatically and use the prepare/perform segue methods. But since the contents in A will never change, I do not want to go that route. Reason why I am trying to find out how to check which segue has been pushed when I select a given row in A. Ideally there would be some for of a method DIDPERFORMSEGUE: (Segue identifier) I could call from the B Viewcontroller.
Thanks very much for your help and suggestions.
In your "A" TableView, you should be able to peek at which row was poked, and then push that information to your "B" table. For example:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"UITableView_B"]){
BTableViewController *vc = (BTableViewController *)[segue destinationViewController];
NSIndexPath *path;
path = [self.tableView indexPathForSelectedRow];
[vc setSelectedPath:path];
}
}
Hope that helps. Best of luck.
Edit: Probably obvious, but in the above "self.tableView" is an outlet pointing at the UITableView.
Update
Personally, I'd bite the bullet and make a class for "A", but in the interest of hacking - it should be possible to reach back and get data from the previous view. This is 'bad code' (imo) and assumes you're using a Navigation Controller - and that the previous view is an "A" table, etc... Without further ado - is should be possible to just do this:
NSArray * views = [self.navigationController viewControllers];
NSUInteger prevViewIndex = [views count] - 2;
UIViewController * previousView = [views objectAtIndex:prevViewIndex];
ATableViewController * aTableViewController = (ATableViewController *) previousView;
NSIndexPath *path = [aTableViewController.tableView indexPathForSelectedRow];
I can't say I've needed to do this myself, but if you really don't want to change the source view controller or if you have a frequent need to identify the segue from the destination view controller, one way to do it would be to create your own UIStoryboardSegue subclass. A segue already knows about the destination view controller, so it's a simple matter to give the destination a chance to inspect the segue. Something like this should do the trick:
#interface MyStoryboardSegue : UIStoryboardSegue
#end
#implementation MyStoryboardSegue
- (void)perform
{
[super perform]
if ([self.destinationViewController respondsToSelector:#selector(didPerformSegue:)]) {
[self.destinationViewController didPerformSegue:self];
}
}
#end
It's not a great solution if you're already using UIStoryboardSegue subclasses for other reasons. And in fact, I haven't even tested the code, so perhaps there are some snags I haven't thought of yet. The point, however, is that if you want a segue to notify the destination when it executes, you can probably arrange it.

Passing data from one view controller to another; iOS <=4 vs iOS 5

First, a little background. I'm new to iOS development, I've been in .Net land for a long time, and that's probably why I'm even asking this question, but here goes.
The basic setup is this. You have a UINavigationController with a RootViewController we'll call MasterViewController. When some action happens on this MasterViewController, we want to drill into a DetailsViewController. However, we also want to pass some data to the DetailsViewController.
It is my understanding, that in previous versions of the SDK (prior to iOS 5) the approach was similiar to this:
#implementation MasterViewController
-(IBAction)someAction
{
DetailsViewController *dvc = [[DetailsViewController alloc]initWithNibName:#"DetailsView" bundle:nil];
dvc.someDataProp = [self getSomeDataSomeHow];
[[self navigationController] pushViewController:dvc animated:YES];
}
#end
Now however, in iOS 5, it seems that this is now done using the Storyboard and segues. In XCode you set up the segue from the MasterViewController to the DetailsViewController, and then in code you do something like this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]];
}
My question is basically this: The older approach somehow feels a lot cleaner to me. You're being very explicit about the type of ViewController you're pushing on to the navigation stack and you can set properties easily on it. In the new approach though, destinationViewController is of type id (for obvious reasons), and it just feels a lot less clean to me. Again, this could be my .Net side coming out, but is this common in iOS? Just use id and throw caution to the wind?
With Storyboards you can assign a named identifier to the segue,
Select the segue and in the Attribute inspector you can add a name to the segue Identifier.
And in the prepareForSegue method you should check for this Identifier and thus you will explicitly know which segue is about to be performed and what the destinationViewController will be.
if ([segue.identifier isEqualToString:#"My First Segue Identifier"])
{
DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController;
// Set the DVC's properties
}
In many cases, the destination view controller for a segue may be a UINavigationViewController, and in that case, the solution (a slight modification of Dennis Mathews' solution above) will need to use the message"topViewController":
if ([segue.identifier isEqualToString:#"My First Segue Identifier"])
{
NavitationViewController* navController = [segue destinationViewController];
DetailsViewController *dvc = (DetailsViewController*) [navController topViewController]
// Set the DVC's properties
}
I haven't been working with iOS that long, but I've seen a few examples where you don't have to cast because of objective-c's loose coupled messaging system.
Instead of checking the segue identifier or casting to a specific ViewController you can do this:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector: #selector(setCompany:)]) {
[segue.destinationViewController performSelector: #selector(setCompany:) withObject: self.company];
}
}
In the first line I ask if the destinationViewController has a method setCompany (if you have a property named company this one would be generated for you). If it does, you can call that method/set that property with the second line of code.
So in this case you don't really have to know the destination ViewController and could easily replace it with a different one that supports handling Companies.

How to properly use modal view controller with the xcode 4.2 storyboard

I was wondering how to properly use the storyboard to put up a view controller modally. Personally I prefer working with xibs, but it seems that the storyboard is gaining popularity and will be the way to go in the future.
The way I would normally put up a view controller modally would be like this: let's say we have ViewControllerA (A for short) and ViewControllerB (B for short).
I would then normally put a protocol in B.h specifying the delegate method when B wants to be dismissed and add the id<theProtocol> delegate field as an assign property. Assuming i'm busy in A and I want to present B modally, I would write:
B* b = [[B alloc] initWithNibName:#"B" bundle:nil];
b.delegate = self;
[self presentModalViewController:B animated:YES];
Using the storyboard, I know it's possible to put up a different view controller in a modal way by ctrl-dragging from a button to a viewcontroller and selecting modal as transition type. I'm just wondering though; where do I set the delegate of the new view controller? What's the correct practice of passing things to your modal view controller? I don't really know what the whole deal with Segues is...
Take a look at this tutorial
According to it, you should set the delegate as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
UINavigationController *navigationController =
segue.destinationViewController;
PlayerDetailsViewController
*playerDetailsViewController =
[[navigationController viewControllers]
objectAtIndex:0];
playerDetailsViewController.delegate = self;
}
}
Where #"AddPlayer" is the name of your 'modal' segue
Instead of using the navigation controller you could directly use the UIStoryboardSegue object passed in prepareForSegue. It has a property called destinationViewController which is the view controller that is being instantiated. I find that a lot cleaner.
This is an example.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
PlayerDetailsViewController
*playerDetailsViewController =
(PlayerDetailsViewController *) segue.destinationViewController;
playerDetailsViewController.delegate = self;
}
}
IMO I think that storyboards are great because they function like a blueprint of your application. Also I've never liked nibs. =D

Resources