Push View from Presented View Controller in iOS

2020-07-01 06:01发布

In Short : How can I PushViewController from Presented ViewController ?

In Brief :

I have MainViewController, In which I have one button on click of button, I am presenting a view called LoginViewController.

On this page (LoginViewController), I again have button, on click of that, I try to push my view controller(called HomeViewController) it doesn't pushes.

Here is my code snippet,

MainViewController.m

- (IBAction)LoginClicked:(id)sender {
    LoginViewController *vc = [[LoginViewController alloc] init];
    [self presentViewController:vc animated:YES completion:nil];
}

LoginViewController.m

- (IBAction)buttonActionMethodOnLoginView:(id)sender{
     NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
     //LoginViewController is not in this array
     HomeViewController *obj = [[HomeViewController alloc] init];
     [self.navigationController pushViewController:obj animated:YES];
}

But it did not works for me. Also, I printed a stack of view controllers before pushed, but it doesn't have LoginViewController. So, without adding LoginViewController into a stack of view controllers, How can I pushed to HomeViewController from LoginViewController ?

When I getBack from HomeViewController, then LoginViewController should get opened..

Is it possible using doing this single NavigationController?

Note:- Here, I have just taken an example using Login, Home and Main ViewController. But I want that into Other Screens.

11条回答
该账号已被封号
2楼-- · 2020-07-01 06:26

You can't push from a presented view controller. I suggest, you should maintain your navigation hierarchy.

For that, from your MainViewController, you should present LoginViewController and you should pass navigation controller for the MainViewController.

- (IBAction)openLogin:(id)sender {
    LoginViewController *loginVC = (LoginViewController *) [self.storyboard instantiateViewControllerWithIdentifier:@"login"];
    [loginVC setReferencedNavigation:self.navigationController];
    [self presentViewController:loginVC animated:YES completion:nil];
}

Then inside LoginViewController, you should push to HomeViewController like this,

LoginViewController.h

@interface LoginViewController : UIViewController {
    UINavigationController *refNavigationController;
}
- (void) setReferencedNavigation:(UINavigationController *)refNavCon;

LoginViewController.m

- (void) setReferencedNavigation:(UINavigationController *)refNavCon {
    refNavigationController = refNavCon;
}

- (IBAction)openHome:(id)sender {
    [self dismissViewControllerAnimated:YES completion:^{
        UIViewController *homeVC = [self.storyboard instantiateViewControllerWithIdentifier:@"home"];
        [refNavigationController pushViewController:homeVC animated:YES];
    }];
}

By doing this, it will be look like, you're pushing from LoginViewController but in reality you're pushing from MainViewController.

You can customize this approach to maintain animation and UI for this flow.

enter image description here

查看更多
\"骚年 ilove
3楼-- · 2020-07-01 06:29

hi when you are Presenting you Login view controller Just present a navigationController like:

LoginVC *loginVCObj =[[LoginVC alloc]initWithNibName:@"LoginVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVCObj];
[self presentViewController:nav animated:YES completion:nil];

Now your PresentedViewController is An navigtioncontroller now you can simply push to your Home VC

  HomeViewController *obj = [[HomeViewController alloc] init];
 [self.navigationController pushViewController:obj animated:YES];

Hope it will helpful for you

查看更多
甜甜的少女心
4楼-- · 2020-07-01 06:29

For Swift 3.0

Present your view controller as a new rootViewController

let navController = UINavigationController.init(rootViewController: self.storyboard!.instantiateViewController(withIdentifier: "SignInViewController"))
self.present(navController, animated: true, completion: {})

Now push your view controller from presented view controller

self.show(self.storyboard!.instantiateViewController(withIdentifier: "SignUpViewController"), sender: self)
查看更多
Fickle 薄情
5楼-- · 2020-07-01 06:31

MainViewController.m

 - (IBAction)LoginClicked:(id)sender {

     LoginViewController *vc = [[LoginViewController alloc] init];

     UINavigationController *loginNav = [[UINavigationController alloc] initWithRootViewController:vc]; 

     [self presentViewController:loginNav animated:YES completion:nil];  

 }

LoginViewController.m

- (IBAction)buttonActionMethodOnLoginView:(id)sender{
     NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
     //LoginViewController is not in this array
     HomeViewController *obj = [[HomeViewController alloc] init];
     [self.navigationController pushViewController:obj animated:YES];
}
查看更多
做个烂人
6楼-- · 2020-07-01 06:34

Create a UINavigationController instance

[[UINavigationController alloc] initWithRootViewController:[[LoginViewController alloc] init]]

Present that navigationController and then push whatever VC you want to.

查看更多
何必那么认真
7楼-- · 2020-07-01 06:36

You have to Push from your firstView (MainViewController), but you can use animation same as PresentView and DismissView. Use following code for this :-

For Push (on MainViewController)

LoginViewController *VC = [[LoginViewController alloc]init];
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition
                                            forKey:kCATransition];
[[[UINavigationController alloc] initWithRootViewController:VC] pushViewController:VC animated:NO];
//[self.navigationController pushViewController:VC animated:NO];

For Pop (on LoginViewController)

CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition
                                            forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];

Using this code, you can get animation same as Present-Dismiss ViewControllers. Refer this answer for more details.

And after that, you can use your code for Pushing LoginViewController to HomeViewController

Hope, this is what you're looking for. Any concern get back to me. :)

查看更多
登录 后发表回答