Using Storyboard ViewControllers - objective-c

What would be main difference between using instantiateViewControllerWithIdentifier and performSegueWithIdentifier ?
I think that performSegue.. is used for normal pushing of viewControllers as instantiateViewController is used for some kind of modal showing of viewController and then dismissing it when used.
Since there are also modal and custom push in storyboard I'm not sure about my theory so if anyone could explain when to use which one ?
Thanks.

The difference is that performSegueWithIdentifier is used to transition to a specific view controller that is connected by a segue in interface builder (Transition1 in my screenshot).
instantiateViewControllerWithIdentifier can be used to instantiate any view controller on a storyboard, regardless if it's connected by a segue or not (Transition2 in my screenshot).
Push, modal, or any other custom transition could be used for either scenario.
instantiateViewControllerWithIdentifier can also be used to instantiate view controllers from separate storyboard files. A segue has to be within the same storyboard file.
The segue identifier used in performSegueWithIdentifier needs to be set in interface builder.
The view controller identifier used in instantiateViewControllerWithIdentifier is the Storyboard ID field in interface builder.

Related

Modally presented view controller can't unwind

I have a UIViewController sublcass (VC1) embedded in a UINavigationController. VC1 triggers a modal segue to another UIViewController subclass (VC2) which is embedded in its own, different UINavigationController. Inside of an action method triggered by a UIBarButtonItem in VC2's nav bar, I call
[self performSegueWithIdentifier:#"SomeString" sender:nil]
which corresponds to an unwind method inside VC1. For some reason, the transition does not occur.
It only became a problem after switching to XCode 6. It worked fine in XCode 5. Any ideas?
This issue has been doing the rounds and I have the exact same problem. Unfortunately there is no good solution to it yet, other than go back to the old delegate pattern.
If you subclass your parent view controller navigation controller and implement - (UIViewController*)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender you will see that the modal is actually looking for your unwindSegue method on the navigation controller instead of the view controller that presented the modal.
The problem gets even more amplified if you have a container view controller as the method above gets called all the way up the controller chain to the storyboard's initial view controller.
There's a potential workaround here Unwind Segue not working in iOS 8 but it has its downsides and side effects as well.

How to use protocol pattern in storyboard

I have used protocol to send data between two view controllers without using storyboard.
ViewControllerB * viewB=[[ViewControllerA alloc] initWithNibName:#"ViewControllerB" bundle:nil];
viewB.delegate=self;
[self.navigationController pushViewController:viewB animated:YES];
How to impliment this with storyboard.
How to impliment this with storyboard.
There's less need to create a protocol to communicate between two view controllers when you use a storyboard. Typically, you'll use storyboard segues to transition between view controllers. When a segue is triggered, the current view controller will get a -prepareForSegue:sender: message, which has the segue as its first parameter. The segue has references to both the "source" and "destination" view controllers, so you can get a reference to the new view controller (the destination) and pass it whatever data you like at that time.
If you do still want to make the current view controller the delegate of the destination and let them use whatever protocol you can dream up, you can set the new controller's delegate in -prepareForSegue:sender:. The rest (creating the protocol, implementing it, etc.) is exactly the same as you've always done.

Adding a UIViewController to a UIView

I have ViewcontrollerA , which is a view made in storyboard.
In this view, i have a UIView that i have added in storyboard and create an outlet to it called containerView.
I wants to add some other viewControllerB (also made in storyboard) to the container.
Tried that :
//add to container a new view from storyboard,with id called serviceView
UIViewController *sv = [self.storyboard instantiateViewControllerWithIdentifier:#"ServiceView"];
[self.containerView addSubview:sv.view];
and got a crash.
How can i do that ?
Thanks .
It most likely crashed because sv is nil, though you should have posted what reason it gave for the crash in your question. If this is the reason, it's probably because your storyboard doesn't contain a view controller with that storyboard identifier. But even if you fixed this, this isn't the proper way of doing view controller containment.
As for adding a view controller to another view controller, you need to use the view controller containment API added in iOS 5. In fact you can even use the storyboard to do view controller containment without writing code. From the Object Library, you can drag out a "Container View". It will let you attach another view controller from your storyboard graphically.

Reuse UIViewController instances when using storyboard

I decided to give the use of storyboards a go in my current iPhone app. I am facing a bit of a problem. I really need to reuse my UIViewController instances.
What do I mean by that? Well, for example I have a table view controller. When I tap a cell, another view controller is loaded from the storyboard and pushed onto the navigation controller stack. This all works well, but it takes about half a second to a second each time this view controller is loaded. Before I was using story boards I simply solved this problem by caching the created instance so the second time you tap a cell the view controller can be immediately shown.
By caching the created instance I mean something like this:
if (!cachedInstance) {
cachedInstance = [MyViewController new];
}
[self.navigationController pushViewController:cachedInstance];
Does anyone know how to accomplish this using the storyboard? Thanks in advance.
If you are using segues, you will need to create custom segues in order to use a cached view controller like you did before. Otherwise, the typical "push" segue will create a new instance of the view controller for segue.destinationViewController. If you write a custom UIStoryboardSegue class and use custom segues you can override initWithIdentifier:source:destination: and put your cached view controller in for the destinationViewController, and then override perform to use the classic pushViewController call.
That is how you handle the segue if you are really intent on using them. I would just skip it though, unless you really want the fancy arrows to lay everything out on your storyboard. If you skip it you can just instantiate the view controllers into the cache and then push them on just like you did before.
If your question is more about locating a view controller inside a storyboard then you can use:
UIViewController *vc = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"Some View Controller"];
Then you can save that to your cache and push it like you did in your example code.
Hope that helps.

How to connect a storyboard to a .h and .m

I have in an app a viewController without a .xib, because I want to use with that ViewController a storyboard instead. The problem is that I don't know how to tell Xcode that ViewController2.storyboard is the view of ViewController2.h and ViewController2.m. Anyone knows it?
When you use storyboards, you generally instantiate the view controller inside the storyboard. The big advantage that storyboards have over .xibs is that they model not just the view hierarchy but also the flow from one view controller to the next. So, you'll probably want to either instantiate your view controller in the storyboard where you plan to use it, or else just go back to loading the view from a .xib (which isn't all that different anyway).