在iOS中从提供的视图控制器推送视图

时间:2016-01-04 12:39:29

标签: ios objective-c uinavigationcontroller pushviewcontroller presentviewcontroller

简而言之: 如何从呈现的ViewController中推送PushController?

简介:

我有MainViewController,我点击按钮时只有一个按钮,我正在展示一个名为LoginViewController的视图。

在此页面上{LoginViewController),我再次点击button,点击它,我尝试推送我的视图控制器(名为HomeViewController),它不会推送

这是我的代码段,

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];
}

但它对我不起作用。另外,我在a stack of view controllers之前打印了pushed,但它没有LoginViewController。因此,如果不将LoginViewController添加到a stack of view controllers,我如何从pushed HomeViewController LoginViewController HomeViewController添加LoginViewController

当我从NavigationController获取后,NoneType' object has no attribute 'get' Request Method: GET Request URL: http://shootnscoreit.com/dashboard/ Django Version: 1.9.1 Exception Type: AttributeError Exception Value: 'NoneType' object has no attribute 'get' Exception Location: /usr/local/lib/python2.7/gettext.py in ugettext, line 400 应该被打开..

是否可以使用此单 usr/local/lib/python2.7/gettext.py in ugettext 400. tmsg = self._catalog.get(message, missing) Local Vars Variable Value message u'Armoury' self <DjangoTranslation lang:no> missing <object object at 0x7f0e72c00740>

注意: - 这里,我刚刚使用Login,Home和Main ViewController进行了示例。但我希望将其纳入其他屏幕。

11 个答案:

答案 0 :(得分:23)

嗨,当您呈现您的登录视图控制器时只需出现一个navigationController,如:

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

现在您的PresentedViewController是一个navigtioncontroller 现在你可以简单地推送到你的家庭VC

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

希望它对你有所帮助

答案 1 :(得分:11)

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

我们的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];
}

具体操作显示LoginViewController。您不希望用户点按back并转到MainViewController。之后,您不希望用户返回LoginViewController。因此,您需要将其显示为模态:

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

现在我们可以看到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];
}

注意:

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

真的应该是:Apple Developer -> "View Controller Programming" documentation,因为这些是您应该了解的核心基础知识&amp;正确设计UX。

这是工作demo sample

答案 2 :(得分:9)

您无法从呈现的视图控制器推送。我建议你应该维护你的导航层次结构。

为此,您应该从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];
}

然后在LoginViewController中,你应该像这样推送到HomeViewController,

  

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];
    }];
}

通过执行此操作,看起来,您正在从LoginViewController推送,但实际上您正在从MainViewController推送。

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

enter image description here

答案 3 :(得分:8)

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];
}

希望它对你有用。

答案 4 :(得分:6)

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

MainViewController.m

创建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

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

关闭

dismissViewControllerAnimated

中致电MainViewController

答案 5 :(得分:4)

创建UINavigationController实例

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

展示导航控制器,然后推送你想要的任何VC。

答案 6 :(得分:4)

<强> 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];
}

答案 7 :(得分:3)

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

- (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];
}

答案 8 :(得分:3)

只需将此代码放在按钮 操作按钮 目标c

UIViewController *yourViewControllerName = [self.storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerName "];

[[self navigationController] pushViewController:yourViewControllerName  animated:YES];

答案 9 :(得分:2)

您必须从第一个视图(PushMainViewController开始,但您可以使用与PresentViewDismissView相同的动画。使用以下代码: -

推送(在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];

适用于Pop (在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];

使用此代码,您可以获得与Present-Dismiss ViewControllers相同的动画。有关详细信息,请参阅this answer

之后,您可以将代码用于Pushing LoginViewControllerHomeViewController

希望,这是你正在寻找的。任何关注都会回复给我。 :)

答案 10 :(得分:2)

对于Swift 3.0

将您的视图控制器显示为新的rootViewController

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

现在从显示的视图控制器推送视图控制器

self.show(self.storyboard!.instantiateViewController(withIdentifier: "SignUpViewController"), sender: self)