Pop to particular controller on iOS | Objective-c - ios

I have the following code to push new ViewControllers.
- (IBAction)btnEditPressed:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"contactListViewController"];
[self parentShowViewController:controller sender:sender];
}
- (void)parentShowViewController:(UIViewController *)controller sender:(id)sender {
if ([self isIOS7]) {
// En iOS7 no existe el método showViewController
[self.navigationController pushViewController:controller animated:YES];
} else {
//[self.navigationController pushViewController:controller animated:YES];
[super showViewController:controller sender:sender];
}
}
Now I have the following scenario: I have 3 ViewControllers called A,B,C.
A->B->C If press back button I want to back from C to A

Try something like this
If you want go to Controller A from controller C on Controller C create custom back button and set the action of it, and put the following code.
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
This is only work if you know that Controller A is your first Controller in Navigation.
If you don't know the order of viewController try this one
for (UIViewController *vc in self.navigationController.viewControllers) {
if ([vc isKindOfClass:[ViewControllerA class]]) {
[self.navigationController popToViewController:VC animated:Yes];
}
}
And to add a custom button go to this link
Hope this will help you.

Related

iOS - a questions about present and push the controllers

There are five controllers here, AViewController, BViewController, CViewController,DViewController,EViewController,controllers here,
A present---> B
B present---> C
C push--->D
D push--->E
Now, if I want to go back from EViewController to AViewController in one step, what code should I write?
[self.navigationController popToRootViewControllerAnimated:animated];
1) Getting the desirable ViewController as Below
for (id controller in [self.navigationController viewControllers])
{
if ([controller isKindOfClass:[AViewController class]])
{
[self.navigationController popToViewController:controller animated:YES];
break;
}
}
2) Here you have A,B,C,D,E Controllers. means A would be on 1 Position so what can you do
you can hard wired the Index as Below
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:0] animated:YES];
3) Pop to the first viewController or rootViewController
[self.navigationController popToRootViewControllerAnimated:animated];
Use unwind segues.
In AViewController add bellow code
-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
}
Go to User Interface of EViewController and Ctrl-drag from the button (you want set action) to the “Exit” outlet, you will see a modal popup.
You can do it recursively with generic solution. First of all you should have reference to A's navigation controller and then you should write recursive method to get active navigation controller like :`
-(UINavigationController*)getActiveNavigationController : (UINavigationController*)navigationController {
if ([navigationController.presentedViewController isKindOfClass:[AViewController class]]) {
return [self getActiveNavigationController:(UINavigationController*)((AViewController*)navigationController.presentedViewController)
];
}
if ((UINavigationController*)navigationController.presentedViewController == nil) {
return navigationController;
}
return [self getActiveNavigationController:(UINavigationController*)navigationController.presentedViewController];
}
`
After that you should write method like
-(void)getInitialScreen:(UINavigationController*)AViewControllerNavigationController {
if ([AViewControllerNavigationController.presentedViewController isKindOfClass:[AViewController class]]) {
return;
}
UINavigationController *navigation = [self getActiveNavigationController:AViewControllerNavigationController];
[navigation dismissViewControllerAnimated:YES completion:^{
[self getInitialScreen:AViewControllerNavigationController];
}];
}
finally after you wrote those 2 methods. You can call them like below and you can always get AViewController
[self getInitialScreen:AViewControlelrnavigationcontroller];
[AViewControlelrnavigationcontroller popToRootViewControllerAnimated:YES];

How t go at specific page in ios

I know this question have been answered before, but i have difficulty to pop on specific page in ios. As i have already tried many times. as i have build 4 pages and and want to move last page to second page.
with the help of this code i have gone through first page
[self.navigationController popToRootViewControllerAnimated:YES];
and with the help of this page i have gone to 3rd page.
[self.navigationController popViewControllerAnimated:YES];
but for second page i have written this code
but it's not working
ViewPage2 *ptwo=[[ViewPage2 alloc] initWithNibName:#"ViewPage2" bundle:nil];
[self.navigationController popToViewController:ptwo animated:YES];
It is because you create new view controller which is not in the stack. What you should do is following:
for (UIViewController *vc in self.navigationController.viewControllers) {
if ( [vc isKindOfClass:ViewPage2]){
[self.navigationController popToViewController:vc animated:true];
return; //optional
}
}
ViewPage2 *ptwo;
for (UIViewController *vc in self.navigationController.viewControllers) {
if ([vc isKindOfClass:[ViewPage2 class]]) {
ptwo = (ViewPage2 *)vc;
break;
}
}
[self.navigationController popToViewController:ptwo animated:true];
Here is the simple answer:
NSArray *arr = [self.navigationController viewControllers];
[self.navigationController popToViewController:[arr objectAtIndex:0] animated:YES];
In place of,
[arr objectAtIndex:0]
here you can give index of specified view controller that you need to pop.
You can try doing this
first import the ViewController on which page u want to go.
like
#import ViewController.h
Then u can do the following
instantiate the class
ViewController *controller = [[ViewController alloc ] init];
[self.navigationController pushViewController:controller animated:YES];
or you can do popToViewController too
for (UIViewController *controller in self.navigationController.viewControllers) {
//Do not forget to import YourViewController.h
if ([controller isKindOfClass:[ViewController class]]) {
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}

Problems with using popToViewController to go back to a specific view controller going to black screen

I am using doing something basic like this to push to a view.
UIStoryboard *storyboard = self.navigationController.storyboard;
MenuViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"menuViewController"];
[self.navigationController pushViewController:viewController animated:YES];
Some places I can simply use:
[self.navigationController popViewControllerAnimated:YES];
But in a few places I want to pop to a specific view controller. What I have tried is:
UIStoryboard *storyboard = self.navigationController.storyboard;
RecordMenuViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"recordMenuViewController"];
[self.navigationController popToViewController:viewController animated:YES];
But it just goes to a black screen like the view isn't in the stack or something. What am I missing here?
If you want to pop to a specific view controller using the navigation stack, do the following:
NSArray* vcs = self.navigationController.viewControllers;
UIViewController* target = [vcs objectAtIndex:([vcs count] - 1) - numVCsToGoBack];
[self.navigationController popToViewController:target];
If you have to pop to specific view controller in the stack use following code:
(here consider you have to pop to MyViewController Class)
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[MyViewController class]])
{
[navigationController popToViewController:controller animated:YES];
break;
}
}

How to get the navigation bar on view controller?

I have three View controller A,B,C.I have navigation controller attached to A view controller.In A i have some buttons,I have attached the button segue to B view controller.Onclick of the button i go to the B view controller.On B View controller i have UITableView on click of table view item i am launching the C view controller.below is the code for that
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
{
NSLog(#"first cell");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
[self presentViewController:vc animated:YES completion:nil];
}
else if(indexPath.row==1)
{
NSLog(#"second cell");
}
else if(indexPath.row==2)
{
NSLog(#"third cell");
}
}
But on C view controller the navigation Bar is not appearing.I think C view controller is not linked to the Navigation Controller.
You use navigationController push method to display navigation bar in C viewController
try this code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
[self.navigationController pushViewController:vc animated:YES];
Use the code below
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];
You need to present it using UINavigationController as modal.
Hope it helps.
use this:
[self.navigationController pushViewController:vc animated:YES];
You can use "Push" segue and embed your ViewController in Navigation Controller, and then use its Navigation Controller's functions like pushViewController and popViewControllerAnimated
Answer are all correct, but i just want to explain things..
//This line gets the storyboard with the name "Main" which contains all
//the setup you made for UI (User interface)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
//While this like gets the view inside your storyboard with
//storyboard ID/indentifier `BusinessCard `
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"BusinessCard"];
//Lastly, this line is correct presenting the viewcontroller BUT this doesn't add your
//viewcontroller to the array of viewControllers inside navigationController
//
//Also, this line makes you present the viewController above the
//rootViewController of window which is in your case the navigationController
//
This is you Error
[self presentViewController:vc animated:YES completion:nil];
//This is what you are looking for, and the correct one for your implementation
//
//This will let you add the `vc`(viewController) to the array of viewController
//in navigationController, to confirm that you can check the `self.navigationController.viewControllers`
//which will return the array of viewController inside your navigationController
This is the Answer
[self.navigationController pushViewController:vc animated:YES];
Hope this helps you, and my explanation is apprehendable.. Cheers

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".

Resources