44

I have a modal storyboard scene that I want to be accessible to all my other scenes. Creating a modal segue to it from every scene on my storyboard creates a big mess of strings going everywhere. Is there a way that I leave off the segues and call the scene programmatically instead?

Basically I want to do something like this:

  MyNewViewController *myNewVC = [[MyNewViewController alloc] init];
  [self presentModalViewController:myNewVC animated:YES];

except instead of creating and pushing a view controller class, I want to do a modal transition to an "isolated" (not connected with a segue) storyboard scene.

kaiz.net
  • 1,984
  • 3
  • 23
  • 31
zakdances
  • 22,285
  • 32
  • 102
  • 173

8 Answers8

87

Yes you can. Do something like this to get access to the VC, then just Modal Push it:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
MyNewViewController *myVC = (MyNewViewController *)[storyboard instantiateViewControllerWithIdentifier:@"myViewCont"];
Mo Abdul-Hameed
  • 6,030
  • 2
  • 23
  • 36
Darren
  • 10,182
  • 20
  • 95
  • 162
  • Does this push the scene as a modal view (like it would with a modal segue)? – zakdances May 09 '12 at 19:58
  • 1
    It depends how you present it. Use [self presentModalViewController:myVC animated:YES]; and it will – Darren May 09 '12 at 19:59
  • Thank you. One thing I'm confused about...what happens to myVC right after the 2nd line but before the "presentModalViewController:myVC" line? Does it just sit in the background hidden? – zakdances May 09 '12 at 20:17
  • It's just allocated and initiated. I'm not too sure if 'ViewDidLoad' is called at that point, you'd have to log it and see. Before presenting it you can assign things to variables you have in that VC. – Darren May 09 '12 at 20:35
  • How can I do the same thing, but instead of a modal scene I want to call a scene thats nested inside a navigation controller? – zakdances May 09 '12 at 23:07
  • Instead of creating MyNewViewController *myVC create UINavigationController *myNav. Make sure you give it an identifier to call. – Darren May 10 '12 at 06:53
  • You can also get the current storyboard's reference with self.storyboard. – Alex Zavatone Jun 26 '14 at 18:27
40

Note: the method presentModalViewController:animated is deprecated in iOS 6.

The new code should read:

NSString * storyboardName = @"MainStoryboard_iPhone";
NSString * viewControllerID = @"ViewID";
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
MyViewController * controller = (MyViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
[self presentViewController:controller animated:YES completion:nil];
Charles Wilson
  • 401
  • 4
  • 2
  • You can also use self.storyboard if you want to make sure you use the same storyboard. – Alex Zavatone Jun 26 '14 at 18:43
  • A little more detail on your first line. Though present**Modal**ViewController:animated *is* deprecated, a replacement for that is presentViewController:animated without the Modal in the middle of the method name. It might not be clear to someone at first glance since the function calls do look pretty much alike. – Alex Zavatone Mar 03 '15 at 20:41
19

In the storyboard give your view controller an identifier (under the Attributes Inspector) then use the following code to bring that view forward.

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"VIEWCONTROLLERIDENTIFIER"];
[self presentModalViewController:vc animated:YES];
WhoaItsAFactorial
  • 3,538
  • 4
  • 28
  • 45
  • 1
    This doesn't seem to work when called from within an AppDelegate. – radven May 10 '12 at 18:53
  • @radven ViewControllers and their classes aren't callable from the AppDelegate (I think)... – Sam Spencer Sep 07 '12 at 01:16
  • 1
    @RazorSharp really? I call into VCs all the time in the AppDelegate (as needed). For example (off the tope of my head), when setting up a root tab bar controller and I need to initialize the view controllers in the tabs. Now, to get things to display you need to work within the App Delegate's presenting of root view controllers/storyboard etc. – chadbag Feb 06 '13 at 01:02
6

I have a case where I want to present a view controller from the main part of the app, one with settings & help & so on. To do this, I want it to be within a nav controller, sort of a little plug in module we can call from a UIBarButtonItem.

Now, this can be to/in the current storyboard, or to another, it doesn't matter.

I want to do it this way, because I loathe the potential of segue line spaghetti all over my storyboard.

Here's how to do it.

- (IBAction)displaySettings:(id)sender
{
    LOG_SELECTOR() // google that for extra goodness

    // FYI, this can be done using a different storyboard like so.
    /*
     NSString * storyboardName = @"MainStoryboard_iPhone"; // possibly use device idiom?
     UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
     */

    // To push a new set of scenes with a new Navigation Controller, it is done like this:
    UINavigationController *settingsNC = [self.storyboard instantiateViewControllerWithIdentifier:@"Settings Nav Controller"];
    OBSettingsUIViewController *settingsVC = [self.storyboard instantiateViewControllerWithIdentifier:@"Settings root"];
    [settingsNC pushViewController:settingsVC animated:NO];

    [settingsNC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];

    // Present the view controller;
    [self presentViewController:settingsNC animated:YES completion:NULL];
}

In the presented view controllers (or in a subclass of the Navigation Controller), you can have a UIBarButtonItem to then dismiss the whole presented hierarchy of view controllers like so:

- (IBAction)dismissThisVC:(id)sender {
     [self dismissViewControllerAnimated:YES completion:nil];
}

Hope this helps a bunch of people out. Cheers.

Alex Zavatone
  • 4,106
  • 36
  • 54
4

enter image description hereJust call viewcontroller using navigation controller Write this code in viewcontroller and set viewcontroller in storyboard as set in the image.

ProfileVC *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ProfileVC"];
[self.navigationController pushViewController:vc animated:YES];
Kaushik Movaliya
  • 799
  • 11
  • 27
3

Call to navigate to other class

UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

UINavigationController *navController = (UINavigationController *)window.rootViewController;

DumpFeed *dump = [storyboard instantiateViewControllerWithIdentifier:@"DumpFeed"];

dump.isPushed=YES;

dump.strUserId = appDelegate.strFriendid;


[navController pushViewController:dump animated:YES];
Vijay Tholpadi
  • 2,135
  • 1
  • 15
  • 20
Bhushan_pawar
  • 157
  • 1
  • 5
3

Heres a Swift version of this:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myVC = storyboard.instantiateViewControllerWithIdentifier("myStoryId")
self.presentViewController(myVC, animated: true, completion: nil)

You should also change your storyboard id like this: enter image description here

Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
1

I think that with iOS7 it has become very easy implementing via the storyboard

I'm currently learning about the new features in iOS7 and found this simple solution, but it might have been relevant even in prior versions, I'm not sure.

First u need to connect the presenting VC with the target VC (thats the only connection needed), then within the storyboard's attributes inspector choose the style to be modal, in the identity inspector give your VC a storyboardID and make sure you checked the 'use storyboardID' checkbox,

If its not there yet add this method to your presentingVC:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

   YourTargetVC * targetVC = 
         (YourTargetVC *)segue.destinationViewController;

   if(nil != targetVC) {

       //Do preparations here
   }

}

Now, when you wish to show your targetVC from your presentingVC you can use:

[self performSegueWithIdentifier:(NSString *) sender:(id)];

where the identifier is your viewController's storyboardID, and the sender is the view who triggered the action, this method will invoke the storyboards scene, so the [prepareForSegue: sender:] method will be called allowing u making last modifications before the targetViewController will appear.

Ankur
  • 5,086
  • 19
  • 37
  • 62
supergegs
  • 39
  • 4
  • 3
    Question was "without needing segue", because "storyboard creates a big mess of strings going everywhere". – Cœur Nov 23 '13 at 11:30
  • Thnx, you are correct. But I think that the original question was published before iOS7 was released. – supergegs Oct 03 '14 at 09:06