push to another view controller without prepareForSegue - ios

How can you push to another view controller without prepareForSegue?
myClassVC *viewController = [myClassVC alloc];
UIStoryboardSegue *segue = [[UIStoryboardSegue alloc] initWithIdentifier:#"pushToMyVC" source:self destination:viewController];
if ([segue.identifier isEqualToString:#"pushToMyVC"]) {
NSLog(#"logging");
myClassVC *viewController = (myClassVC *)[segue destinationViewController];
[self presentViewController:viewController animated:YES completion:nil];
}

If you want to programmatically invoke a push segue, you give the segue a "storyboard id" in Interface Builder and then you can:
[self performSegueWithIdentifier:"pushToMyVC" sender:self];
Alternatively, if you don't want to perform the segue, you can instantiate the destination view controller and then manually push to that view controller. All you need to do is to make sure that the destination view controller has its own "storyboard id" in Interface Builder, then you can:
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"DestinationController"];
[self.navigationController pushViewController:controller animated:YES];
You said "push" (and hence I used pushViewController above). If you really meant to "present a modal view controller", then that second line is:
[self presentViewController:controller animated:YES completion:nil];
As you can see, you don't have to use prepareForSegue to push to new scene. You only use prepareForSegue if you want to pass information to the destination view controller. Otherwise it is not needed.
Clearly, if you're not using storyboards (e.g., you're using NIBs), then the process is entirely different. But I assume you're not using NIBs because prepareForSegue is not applicable in that environment. But if you were using NIB, it would be as follows:
SecondViewController *controller = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];

[self presentViewController:viewController animated:YES completion:nil]; is not needed, as the segue will push the destination view controller using the transition you selected automatically.
If you don't want to use the segue process you'll need to manually push the view controller with:
[self presentViewController:viewController animated:YES completion:nil];
but make sure you remove the segues in the Storyboard first.

NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID"];
[self presentViewController:vc animated:YES completion:nil];

In my case all viewControllers are built dynamically. I do not make use of the storyboard for this purpose. Should this be your case you may just instantiate the viewController class you want to open and make a push as in my example below:
MyViewController* myViewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];

Related

How to present a view controller programmatically

I have a button inside my nib file. How can I programmatically present another view controller when the user taps on this button?
As I understood , you want to push new viewController on Button click . Please try this
- (IBAction)buttonClicked {
MyViewController *myViewController = [[MyViewController alloc]init];
[self presentViewController: myViewController animated:YES completion:nil];
}
First you need to create an action for your button, normally via Ctrl+drag. On that action implementation you should alloc the destination ViewController. The code would be something like this:
- (IBAction)buttonTapped {
MyViewController *modalViewController = [MyViewController new];
[self presentViewController:modalViewController animated:YES completion:nil];
}
Since you said that your file is a nib, I'm assuming that you aren't on a storyboard with both ViewControllers on it and the ViewController to be presented is code based. If this isn't the case, please elaborate your question.
As requested: Loading a VC from a storyboard
- (IBAction)buttonTapped {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
RSSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"RSSVC"];
// OR If is initial
// RSSViewController *viewController = [storyboard instantiateInitialViewController];
viewController.feedURL = #"...";
[self presentViewController:viewController animated:YES completion:nil];
}
If you need, ViewController identifier should be set in the Identity Inspector in the Storyboard.
Refer the below screenshots
First : control+drag the button
Second: Once you release the mouse,it shows you the box
Third:Click Connection Dropdown box.It shows you 3 option
Fourth:Choose or Select Action from the drop down.
Five : Finally give action name
now in ViewContoller.h the action method is
- (IBAction)actionGoNextPage:(id)sender;
Then in ViewContoller.m
#import "SecondViewController.h"
- (IBAction)actionGoNextPage:(id)sender
{
SecondViewController *secondVC = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
[self presentViewController:secondVC animated:YES completion:nil];
}

How to open new view controller after click button?

I added one ViewController to my project and created one class.
After I bind this class to my ViewController.
In another controller I have method:
- (IBAction)login:(id)sender {
// How here I can do redirect to controllerViewController
}
There are two ways to push view controllers in the application.
1) by Segue
2) By View controller identifier
1) By Segue :
[self performSegueWithIdentifier:"SegueIdentifier" sender:self];
2) By View controller identifier :
Yourclassname *gotoYourClass = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerIdentifier"];
[self.navigationController pushViewController:gotoYourClass animated:YES];
- (IBAction)login:(id)sender {
ViewController *vc = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self presentViewController:vc animated:YES completion:nil]; }
In the storyboard give your view controller an identifier (under the Attributes Inspector) then use the following code, to bring that view forward.
IF YOU WANT TO USE PUSH THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self.navigationController pushViewController:vc animeted:YES];
IF YOU WANT TO PRESENT THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self presentModalViewController:vc animated:YES];
Note: In UIViewController please enter your view controller name which you want to push into another view.
If you want to comeback to the current ViewController later then use Navigation ViewController or else just use the presentedViewController of self(your current viewController)- no going back business, like they have previously illustrated.
For a simple block of execution(demo or practice) it's all the same but for a project application it completely matters to make the correct choice.

What is the best practice to switch between view controllers for iOS in Objective-C

What is the best practice to switch between UIViewControllers for iOS in Objective-C? Now I have a menu UIViewController and a game's main screen UIViewController. In the menu there's a "New game" UIButton which should switch to the game's main controller. I do it like this:
- (IBAction)newGameButtonClicked:(id)sender {
ViewController *gameViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"GameViewController"];
[self presentViewController:gameViewController animated:NO completion:^{
// ...
}];
}
When player dies, other view controller should be showed and I do it in the similar way like this:
MenuViewController *menuViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"MenuViewController"];
[self presentViewController:menuViewController animated:NO completion:^{
// ...
}];
Is it right or there is a better way to achieve this behavior?
Thanks in advance.
If you want to init an UIViewController from the UIStoryboard you can do it like in your example. I would just use a UINavigationController as parent UIViewController and push them to the UINavigationController.
NSString *strVC = [NSString stringWithFormat:#"%#", [MenuViewController class]];
MenuViewController *menuViewController =
[self.storyboard instantiateViewControllerWithIdentifier:strVC];
[self.navigationController pushViewController:menuViewController
animated:YES];
When using segues like #mehinger explained, use [segue destinationViewController]. But this is just needed if you want to set any variables to the UIViewController before pushing it.
If you're in a Navigation Controller:
ViewController *viewController = [[ViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
or if you just want to present a new view:
ViewController *viewController = [[ViewController alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
If you want to present a new viewcontroller in the same storyboard,
In CurrentViewController.m,
import "YourViewController.h"
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
YourViewController *viewController = (YourViewController *)[storyboard instantiateViewControllerWithIdentifier:#"YourViewControllerIdentifier"];
[self presentViewController:viewController animated:YES completion:nil];
or if you are using navigation controller:
[self.navigationController pushViewController:viewController animated:YES];
To set identifier to a view controller, Open MainStoryBoard.storyboard. Select YourViewController View-> Utilities -> ShowIdentityInspector. There you can specify the identifier.
Segues are the way to do when switching between view controllers:
- (IBAction)newGameButtonClicked:(id)sender {
[self performSegueWithIdentifier:#"goToGameViewController"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if(segue.identifier isEqualToString:#"goToGameViewController") {
GameViewController *gameViewController = [GameViewController new];
//do any other preparation you would like
}
}
In your storyboard you can then drag a segue from one view controller to the other and indicate its identifier as "goToGameViewController".

Need to return to the presenting UIViewController from within a presented UINavigationController

In MyMainViewController, I present a navigation controller like this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UINavigationController* nc = [storyboard instantiateViewControllerWithIdentifier:#"NAVIGATION_CONTROLLER_ID"];
[self presentViewController:nc animated:YES completion:nil];
Later, from somewhere within the view hierarchy of the UINavigationController, I need to return to MyMainViewController. How can I do this?
(Note: MyMainViewController is defined in a .XIB, and not in the storyboard where the UINavigationController and it's children are defined.)
It sounds like you have modally presented a NavController that you want to remove. Modally presented VC's can remove themselves.
Somewhere in your NavController add:
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Dismissed nav controller modally");
}]
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:2] animated:YES];
I gues you know the index of your view controller. If you simply want to return to the rootViewController you can do it like
[self.navigationController popToRootViewControllerAnimated:YES];
If you want to push new viewController to the navigation stack just do it like
MyMainViewController *mainController = [[MyMainViewController alloc] initWithNibName:#"MyMainViewController" bundle:nil];
[self.navigationController pushViewController:desController animated:YES];
Returning to the previous viewController would be
[self dismissViewControllerAnimated:YES completion:nil];

how to transit to a view controller

I made a view controller A in storyboard and linked with other view controller. Now I have another view controller B and I want to write a method that can transit from B to A. How can I do this?
There is a segue to controller A in storyboard.
And controller B is loaded from another view I created programmatically so I can't set a segue in storyboard.
Since you are using storyboard. This is more accurate, try this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"YOUR VIEW CONTROLLER"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
But be sure to name your view's identifier otherwise it will crash and wont work.
Then when you want to dimiss the view:
[self dismissModalViewControllerAnimated:YES];

Resources