iOS storyboards instantiate viewController and IBAction - ios

I may go mad very soon.
This is the reason:
- I started up with Single View Application project with storyboards. Then I set the view controller class name in the storyboard for my viewController.
- Next step I created one pointer for this viewController in AppDelegate method ...didFinishLaunchingWithOpt... and filled it up by calling [myStoryboards instantiate...]. It works pretty good because I can call method like [vc1 setMyName] which does smthng like self.myName = #"Johnny";
- But here it comes. When I create IBAction method joined with button, this method doesn't know anything about "Johhny". And this is because I'm in another instance. When I check the address of "self" it is another one...
WhyWhyWhy??? Please help, how can I use still the same object - the one instantiated in AppDelegate by storyboards and the one from storyboards in "interface builder".
Thank you.
Oh my. I think I really underestamated it...
When we were talking about getting pointer of other viewControllers from storyboard...
I have initialViewController got by calling rootViewContr... And another one connected with segue (modal) where is UITableView. A get data on rootViewController and I want to show them on the other one in the list (UITableView). So I call segue (performSegueWithIdentifier), the other controller is shown but the list is clear. Because the method I call is working with tableView variable which is null :/ Because, again, I'm in another object. That is because I call that method storyboard instantiate... How can I get exactly the same viewController which I'm working in storyboard with. It is quite confusing for me :/
I read something about prepareForSegue and getting the pointer by destinationViewController but that is not what exactly I want. I need the pointer before I call segue method and the viewController is shown...
Thank you.

If you've set up your initial view controller properly in the storyboard, you don't need to assign it to the windows rootViewController property in -applicationDidFinishLaunchingWithOptions: as this is done for you automatically. It sounds like you're creating a second instance. To access the original instance setup by the storyboard simply do this in -applicationDidFinishLaunchingWithOptions:
InitialViewController *viewController = (InitialViewController *)self.window.rootViewController;
viewController.myName = #"Johnny";

Related

SWRevealViewController and passing objects

I want to pass an object to my rear UIViewController when I reveal it. I set up the SWRevealViewController in the interface builder. I tried passing it in prepareForSegue for segue id "sw_rear" however I noticed that this isn't even called when the controller is revealed. Could anyone give me a pointer on how to do this please?
I had the same issue before.
prepareForSegue is not called from controllerA as it does not own controllerB.
You can access to your rear just writting: self.revealViewController.rearViewController from any instance that inherits from SWRevealViewController.

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

Loop loading UIViewControllers in storyboards

I'm using storyboard and i want to know if there is a way to use a UINavigationController to navigate from A->B->A->B and so on. The UIViewControllers are the same but the info loaded in each one is different.
I tried using segues but the problem is that the info loaded into the classes is not saved. So when i do A->B->A and i go back to the root, the info of root is the info loaded in the 2ยบ A. Because i'm using storyboards i don't create instances of the UIViewControllers and i think that is the problem, i only use [segue destinationViewController] in prepareForSegue. I think that one solution would be stop using storyboards and use Xibs, because that way i would create an instance of each class every time they were loaded and that would solve my problem.
I just wanted to know if there is a way to do this using storyboard, because changing to Xibs, would need a lot of work. Any suggestions?
I've never tried to do A -> B -> A -> B before. But I have tried to do A -> A -> A, and that doesn't work. A limitation of Storyboards is that you can't segue to another instance of the same VC.
However what you can do is pretty easy - instead of writing up the button to triggering a segue in the storyboard, wire it up to a method and push the new view controller onto the navigation stack manually.
- (IBAction)buttonTapped:(id)sender {
UIViewController *viewControllerA = [self.storyboard instantiateViewControllerWithIdentifier:#"viewControllerAIdentifier"];
[self.navigationController pushViewController:viewControllerA];
}
Note that "prepareForSegue" won't get called here so you'll have to configure the new VC instance as needed.

Two UIviewControllers inside UIScrollview - how to call methods between them

I have problem with calling methods from one UIViewController by another UIViewController.
Currently I have UIScroll view with two UIViewControllers.
I want to change something in second one and see results in first one.
I try to do this in this way:
Inside function of second UIViewController:
-(void)doSomething:(){
FirsOneViewController *firstVC = [FirsOneViewController alloc] init];
[firstVC changeUnits:0];
}
Function is called but I don't se any changes in first controller.
BR,
Paul
From your code I see you create a new instance of FirstViewController and so there is no reason why the current instance inside the scrollview would receive this message.
You need to send the changeUnits: message to the current FirstViewController, so you need a reference to it. To do this you may want to think about creating a protocol, so that you parent container (the scrollview) is notified by the SecondViewController and then notifies the FirstViewController. A simpler(and lazier) solution is make the SecondViewController have a strong reference to the FirstViewController (though this solution may bite you in the future).
As said in other answers you are creating a new instance of FirsOneViewController instead of referencing to the one you already have.
Here are three ways of doing what you are asking:
Delegation:
The FirstViewController should be the delegate of the SecondViewController (as the secondViewController is calling methods on the FirstViewController). You should tell the SecondViewController that the FirstViewController is its delegate in what ever class initialises the two viewControllers.
From what you have said so far this seems like your best option.
NSNotification:
This could be good option if you think more than one object will want to listen to the change in the SecondViewController. Just post an NSNotification in the SecondViewController and add an NSNotification listener in the FirstViewController
Singleton:
if there should only ever be one instance of the FirstViewController in existence then make it a singleton. By making a class initialiser method. so that you can create/get the current instance of the object from anywhere in your appellation.
Hope this helped.

performSegueWithIdentifier replacing detailViewController works, but prepareForSegue is not called

I have an app created from Xcode 4.5's boilerplate Master-Detail Application with CoreData, StoryBoards and ARC turned-on that is not calling prepareForSegue. CoreData isn't currently being used, but it will be to cache XML responses. performSegueWithIdentifier works, but prepareForSegue isn't and I'm having troubles passing/access data from the MasterViewController to/in the detailViewController created by performSegueWithIdentifier.
My basic set-up is similar to what's discussed in the thread: Storyboards and UISplitViewControllers. There's an image of a storyboard on page three that's very similar to my set-up (I don't have enough rep to post images).
In a nutshell:
I create a standard splitView arrangement
The MasterViewController builds the main table
Each cell corresponds to a URL that returns XML data that determines what's in the detailView
The fetched XML is parsed using a NSXMLParser operation/class
The fetched XML determines which detail view is needed and the MasterViewController calls the appropriate 'replace' segue (via performSegueWithIdentifier) to kick-off the corresponding detailViewController to display the fetched XML
The problem that I'm having is that prepareForSegue isn't being called, so I can't pass the fetched XML to the detailViewController.
What I need is one of the following:
prepareForSegue to be executed
a way to know segue.destinationViewController inside handleLoadedResponse:notif
a way to get access to the "currentResponse" variable in the MasterViewController from inside the viewDidLoad method of the detailViewControllers
a way to find the MasterViewController via its StoryBoardID
What I've tried:
Putting NSLog() statements in each viewController's prepareForSegue -- none of them are called
Digging through the self.parentViewController chain in the detailViewController to find the MasterViewController that called performSegueWithIdentifier -- I can't find the class variable I'm looking for
Read pretty much every "prepareForSegue not called" post I could find -- They all seem due to some coding/storyboard error that I don't see in my code/storyboard
Could the problem be that I'm calling:
[self.navigationController performSegueWithIdentifier:#"theDesiredSegue" sender:self];
from inside the handleLoadedResponse:notif call-back and the app is trying to call prepareForSegue in my parsing object?
TIA
Ray
Well, chalk this up to staring at the code too long and/or newbie-ness.
After triple-checking everything that I though was obvious, I thought the only thing left was that the segue code didn't behave correctly inside the NSXMLParser call-back, so I switched the handleLoadedResponse:notif routine to store the parsed data and send-out notifications.
While debugging those changes, I realized that my segues were attached to the wrong object. They were actually attached to the navigationController and not my viewController. Visually, things looked like the story board on page three of RWForums: Storyboards and UISplitViewControllers, but they really weren't. The end result being that even though it seemed like my code was calling performSegueWithIdentifier and that it's prepareForSegue method should have been called, it was actually calling the navigationController's segue, so the navigationController's inherited prepareForSegue was being called.
Recommendation: Make sure you re-re-re-check all the connections in the StoryBoard Editor with the Document Outline open.
Ray

Resources