从 iOS 中的呈现视图控制器推送视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34591394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:31:18  来源:igfitidea点击:

Push View from Presented View Controller in iOS

iosobjective-cuinavigationcontrollerpushviewcontrollerpresentviewcontroller

提问by Meet Doshi

In Short :How can I PushViewController from Presented ViewController ?

简而言之:如何从呈现的 ViewController 中 PushViewController ?

In Brief :

简单来说 :

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

我有MainViewController,其中我有一个单击按钮的按钮,我正在呈现一个名为 的视图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.

在这个页面 ( LoginViewController) 上,我再次有button,点击它,我尝试推送我的视图控制器(称为HomeViewController),它没有推送。

Here is my code snippet,

这是我的代码片段,

MainViewController.m

主视图控制器.m

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

LoginViewController.m

登录视图控制器.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 controllersbefore pushed, but it doesn't have LoginViewController. So, without adding LoginViewControllerinto a stack of view controllers, How can I pushedto HomeViewControllerfrom LoginViewController?

但它对我不起作用。另外,我a stack of view controllers之前打印过pushed,但它没有LoginViewController。因此,无需添加LoginViewControllera stack of view controllers,我怎么能pushedHomeViewControllerLoginViewController

When I getBack from HomeViewController, then LoginViewControllershould get opened..

当我从 返回时HomeViewControllerLoginViewController应该打开..

Is it possible using doing this single NavigationController?

可以使用做这个单NavigationController吗?

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

注意:-在这里,我刚刚使用 Login、Home 和 Main ViewController 举了一个例子。但我希望它进入其他屏幕。

采纳答案by Meet Doshi

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

您必须Push从 firstView ( MainViewController) 开始,但您可以使用与PresentView和相同的动画DismissView。为此使用以下代码:-

For Push(on MainViewController)

对于推送(上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)

流行音乐(上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 answerfor more details.

使用此代码,您可以获得与Present-Dismiss ViewControllers. 有关更多详细信息,请参阅此答案

And after that, you can use your code for PushingLoginViewControllerto HomeViewController

在这之后,你可以用你的代码PushingLoginViewController,以HomeViewController

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

希望,这就是你要找的。有任何问题都可以回复我。:)

回答by Shubham bairagi

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

现在您的 PresentedViewController 是一个导航控制器,现在您可以简单地推送到您的家庭 VC

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

Hope it will helpful for you

希望对你有帮助

回答by Vive

LoginViewControllershould not be pushed to navigation controller stack. Let me describe below "why".

LoginViewController不应推送到导航控制器堆栈。让我在下面描述“为什么”。

Our MainViewControllershould be on the stack - you always want to go back there.

我们MainViewController应该在堆栈上 - 你总是想回到那里。

// AppDelegate.m (only if you don't use storyboards, if you do - you don't need to copy this part of code)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // create the window
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self.window setBackgroundColor:[UIColor whiteColor]];
    [self.window makeKeyAndVisible];

    // set view controllers
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[MainViewController alloc] init]];
    [self.window setRootViewController:navigationController];
}

On specific action show LoginViewController. You don't want the user to be able to tap backand go to MainViewController. Later, you won't want user to go back to LoginViewController. Because of this, you need to present it as modal:

上具体动作表演LoginViewController。您不希望用户能够点击back并转到MainViewController。稍后,您将不希望用户返回LoginViewController. 因此,您需要将其呈现为模态:

// inside `MainViewController.m`
- (IBAction)myCoolActionToShowLogin:(id)sender {
    [self presentViewController:[[LoginViewController alloc] init] animated:YES completion:nil];
}

Now we can see LoginViewController. When user completes the login, dismiss it and present HomeViewController:

现在我们可以看到LoginViewController。当用户完成登录时,关闭它并显示HomeViewController

// inside `LoginViewController.m`
- (IBAction)myAwesomeActionToShowHome:(id)sender {
    UINavigationController *navigationController = (UINavigationController *)[UIApplication.sharedApplication.keyWindow rootViewController];
    [navigationController pushViewController:[[HomeViewController alloc] init] animated:YES];
    [self dismissViewControllerAnimated:YES completion:nil];
}

NOTES:

笔记:

As you may notice, myAwesomeActionToShowHome:expects you have navigation controller as your rootViewController. This is working, but should be nicer - you should check if that navigation is in fact navigation controller instead of casting it. Or you may create a delegate or block to push new one. This is the fastest, easiest working solution, which should be improved later.

您可能会注意到,myAwesomeActionToShowHome:希望您将导航控制器作为您的rootViewController. 这是有效的,但应该更好 - 您应该检查该导航是否实际上是导航控制器而不是投射它。或者你可以创建一个委托或块来推送新的。这是最快、最简单的工作解决方案,以后应该改进。

You reallyshould read: Apple Developer -> "View Controller Programming" documentation, as these are the core fundamentalsyou should know to develop & design UX correctly.

真的应该阅读:Apple Developer -> "View Controller Programming" 文档,因为这些是正确开发和设计 UX 应该知道的核心基础知识。

Here is the working demo sample.

这是工作演示示例

回答by Hemang

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.

为此,从您的 MainViewController,您应该显示 LoginViewController,并且您应该传递 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 中,你应该像这样推送到 HomeViewController,

LoginViewController.h

登录视图控制器.h

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

LoginViewController.m

登录视图控制器.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.

通过这样做,看起来就像是从 LoginViewController 推送,但实际上是从 MainViewController 推送。

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

您可以自定义此方法来维护此流的动画和 UI。

enter image description here

在此处输入图片说明

回答by Rohit Pradhan

1) present a navigation controller with itsroot view controller` set as view controller .

1) 呈现一个navigation controller with its根视图控制器`设置为视图控制器。

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

- (IBAction)buttonActionMethodOnLoginView:(id)sender
{
    HomeViewController *obj = [[HomeViewController alloc] init];
    [self.navigationController pushViewController:obj animated:YES];
}

Hope it will work for you.

希望它对你有用。

回答by ukim

The problem is that LoginViewControllerhas no navigation controller. Then you give it one.

问题是LoginViewController没有导航控制器。然后你给它一个。

MainViewController.m

主视图控制器.m

Create a UINavigationController, put LoginViewControllerin to the stack and present the UINavigationController.

创建一个UINavigationController,放入LoginViewController堆栈并呈现UINavigationController.

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

LoginViewController.m

登录视图控制器.m

- (IBAction)buttonActionMethodOnLoginView:(id)sender{
    HomeViewController *obj = [[HomeViewController alloc] init];
    [self.navigationController pushViewController:obj animated:YES];
}

Dismiss

解雇

Call dismissViewControllerAnimatedin your MainViewController.

调用dismissViewControllerAnimated您的MainViewController.

回答by emraz

For Swift 3.0

对于 Swift 3.0

Present your view controller as a new rootViewController

将您的视图控制器呈现为新的 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)

回答by Bera Bhavin

This is very simple code for present view controller and push view controller.

这是当前视图控制器和推送视图控制器的非常简单的代码。

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

- (IBAction)buttonActionMethodOnLoginView:(id)sender{
        HomeViewController *objHomeVC = [[HomeViewController alloc] init];
        [self.navigationController pushViewController:objHomeVC animated:YES];
}

回答by Hunaid Hassan

Create a UINavigationController instance

创建一个 UINavigationController 实例

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

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

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

呈现该导航控制器,然后推送您想要的任何 VC。

回答by darshan

MainViewController.m

主视图控制器.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

登录视图控制器.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];
}