69

我有一个视图控制器层次结构和最上面的控制器被显示为模式和想知道如何显示导航栏使用presentViewController和显示导航栏

'UIViewController:presentViewController:viewControllerToPresent:animated:completion' 

关于“presentViewController该文档时:注:

'在iPhone和iPod touch上,呈现的视图始终为全屏。 在iPad上,演示文稿取决于 modalPresentationStyle属性中的值。'

对于“modalPresentationStyle”,文档说:

呈现样式决定如何一个模态呈现视图控制器在屏幕上显示。在iPhone和iPod touch上,模式视图控制器总是全屏显示,但在iPad上有几种不同的显示选项。

有没有办法确保导航栏在状态栏下方可见,一旦视图控件显示出来?我是否应该将文档解释为,您没有获得iPhone/iPod的任何选项,只能在iPad上使用?

以前,我使用的是'UIViewController:presentModalViewController:animated',它工作正常,但自iOS 5.0以来,API已被弃用,因此我正在切换到新的。

从视觉上看,我期望做的就是让新控制器从屏幕底部滑入,就像旧API一样。

[代码为更新]:

// My root level view: 
UIViewController *vc = [[RootViewController alloc] 
          initWithNibName:nil 
          bundle:[NSBundle mainBundle]]; 
navController = [[UINavigationController alloc] initWithRootViewController:vc];   
.... 

// Within the RootViewController, Second view controller is created and added 
// to the hierarchy. It is this view controller that is responsible for 
// displaying the DetailView: 
SecondTierViewController *t2controller = [[SecondTierViewController alloc] 
              initWithNibName:nil 
              bundle:[NSBundle mainBundle]]; 

[self.navigationController pushViewController:t2controller animated:YES]; 

// Created by SecondTierViewController 
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                     
             bundle:[NSBundle mainBundle]]; 

controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
controller.modalPresentationStyle = UIModalPresentationCurrentContext; 

[self.navigationController presentViewController:controller 
             animated:YES 
             completion:nil]; 

回答

163

这是事实,如果你目前在iPhone上一个视图控制器模态,它总是会不管你如何表现它导航控制器的顶视图控制器上呈现全屏或任何其他方式。但你总是可以显示导航栏是这样的:

而不是呈现该视图控制器模式地设置为视图控制器的根视图控制器模态呈现导航控制器,你想:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil]; 
UINavigationController *navigationController = 
    [[UINavigationController alloc] initWithRootViewController:myViewController]; 

//now present this navigation controller modally 
[self presentViewController:navigationController 
        animated:YES 
        completion:^{ 

         }]; 

你应该看到一个导航栏,当你的视图模态地呈现。

+0

这几乎是我开始的。但是我没有使用'presentModalViewController'的原因是因为它被称为不赞成使用的API。 – 2012-03-15 18:22:09

+0

这是在UIViewController类中写入的内容: //将另一个视图控制器显示为模态子项。如果使用动画,则使用垂直图纸过渡。此方法已由presentViewController取代:动画:完成: //将进行相应的计划。 (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated; 所以只需调用新方法并通过零来完成,你应该很好。 – 2012-03-15 18:24:34

+0

很好的回答。更新为使用'(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void(^)(void))completion' – 2014-07-18 15:00:59

0

如果您没有设置modalPresentationStyle属性(如到UIModalPresentationFormSheet),导航栏会一直显示。为确保始终如一

[[self.navigationController topViewController] presentViewController:vieController 
                  animated:YES 
                  completion:nil]; 

这将始终显示导航栏。

+0

嗯..即使对'topViewController'的固定引用,我仍然看到相同的行为。我不认为我以任何特殊方式将其他视图控制器添加到导航堆栈中。 – 2012-03-15 17:55:17

0

一个解决方案

DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                     
             bundle:[NSBundle mainBundle]]; 

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller]; 
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
navController.modalPresentationStyle = UIModalPresentationCurrentContext; 



[self.navigationController presentViewController:navController 
             animated:YES 
             completion:nil]; 
+0

它根本不工作 – 2013-06-14 13:54:16

+0

它解决了我的问题 – Clement 2018-02-13 13:54:17

22

你可以使用:

[self.navigationController pushViewController:controller animated:YES]; 

让我们回到(我认为):

[self.navigationController popToRootViewControllerAnimated:YES]; 
+3

谢谢,如果您的故事板中已经有导航控制器设计,那么最好的办法就是做到这一点。你帮了我很多 – phyzalis 2014-03-04 01:11:36

+0

回去是[self.navigationController popViewControllerAnimated:YES]; popToRoot - 一路回到第一个视图控制器 – 2017-02-01 19:08:36

1

所有一[self.navigationController pushViewController:controller animated:YES];确实是动画过渡,并将其添加到导航控制器堆栈,以及其他一些酷导航栏动画的东西。如果你不关心酒吧动画,那么这个代码应该工作。该栏确实出现在新的控制器上,并且您可以获得交互式的流行手势!

//Make Controller 
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                     
            bundle:[NSBundle mainBundle]]; 
//Customize presentation 
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
controller.modalPresentationStyle = UIModalPresentationCurrentContext; 

//Present controller 
[self presentViewController:controller 
        animated:YES 
       completion:nil]; 
//Add to navigation Controller 
[self navigationController].viewControllers = [[self navigationController].viewControllers arrayByAddingObject:controller]; 
//You can't just [[self navigationController].viewControllers addObject:controller] because viewControllers are for some reason not a mutable array. 

编辑:对不起,presentViewController将填满整个屏幕。您需要进行自定义转换,使用CGAffineTransform.translation或其他方法,使用转换对控制器进行动画处理,然后将其添加到navigationController的viewControllers。

1

我在ios7上遇到了同样的问题。我在选择器中调用它,它在ios7和ios8上都可以工作。

[self performSelector: @selector(showMainView) withObject: nil afterDelay: 0.0]; 

- (void) showMainView { 
    HomeViewController * homeview = [ 
     [HomeViewController alloc] initWithNibName: @ 
     "HomeViewController" 
     bundle: nil]; 
    UINavigationController * navcont = [ 
     [UINavigationController alloc] initWithRootViewController: homeview]; 
    navcont.navigationBar.tintColor = [UIColor whiteColor]; 
    navcont.navigationBar.barTintColor = App_Theme_Color; 
    [navcont.navigationBar 
    setTitleTextAttributes: @ { 
     NSForegroundColorAttributeName: [UIColor whiteColor] 
    }]; 
    navcont.modalPresentationStyle = UIModalPresentationFullScreen; 
    navcont.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; 
    [self.navigationController presentViewController: navcont animated: YES completion:^{ 

    }]; 
} 
0

我使用此代码。它的正常工作中的iOS 8

MyProfileEditViewController *myprofileEdit=[self.storyboard instantiateViewControllerWithIdentifier:@"myprofileeditSid"]; 
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myprofileEdit]; 
[self presentViewController:navigationController animated:YES completion:^{}]; 
20

雨燕3.0/4.0

导航:

guard let myVC = self.storyboard?.instantiateViewController(withIdentifier: "MyViewController") else { return } 
let navController = UINavigationController(rootViewController: myVC) 

self.navigationController?.present(navController, animated: true, completion: nil) 

回去:

self.dismiss(animated: true, completion: nil) 

夫特2.0

导航:

let myVC = self.storyboard?.instantiateViewControllerWithIdentifier("MyViewController"); 
let navController = UINavigationController(rootViewController: myVC!) 

self.navigationController?.presentViewController(navController, animated: true, completion: nil) 

回去:

self.dismissViewControllerAnimated(true, completion: nil) 
+0

但如何设置当我尝试你的代码,然后只设置导航栏,但我不能改变它的属性像棒色彩,标题等 – Jaydip 2017-10-09 05:59:39

+0

你是什么问题@Jaydip? – 2017-10-09 06:01:17

+0

navigationBartintColor不变 – Jaydip 2017-10-09 07:26:04

0

如果您在斯威夫特2.x中使用NavigationController

let storyboard = UIStoryboard(name: "Main", bundle: nil) 
let targetViewController = storyboard.instantiateViewControllerWithIdentifier("targetViewControllerID") as? TargetViewController 
self.navigationController?.pushViewController(targetViewController!, animated: true) 
0

试试这个

 let transition: CATransition = CATransition() 
    let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 
    transition.duration = 1 
    transition.timingFunction = timeFunc 
    transition.type = kCATransitionPush 
    transition.subtype = kCATransitionFromRight 
    self.view.window!.layer.addAnimation(transition, forKey: kCATransition) 
    self.presentViewController(vc, animated:true, completion:nil) 
0

斯威夫特版本: 这提出并嵌入导航控制器,一个视图控制器。

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    // Identify the bundle by means of a class in that bundle. 
    let storyboard = UIStoryboard(name: "Storyboard", bundle: NSBundle(forClass: SettingsViewController.self)) 

    // Instance of ViewController that is in the storyboard. 
    let settingViewController = storyboard.instantiateViewControllerWithIdentifier("SettingsVC") 

    let navController = UINavigationController(rootViewController: settingViewController) 

    presentViewController(navController, animated: true, completion: nil) 

} 
1

夫特3

 let vc0 : ViewController1 = ViewController1() 
     let vc2: NavigationController1 = NavigationController1(rootViewController: vc0) 
     self.present(vc2, animated: true, completion: nil) 
+0

如何将BACK按钮添加到呈现的UIViewController – 2017-05-09 09:55:06

+0

@zulkarnainshah那是什么? – BennyTheNerd 2017-05-11 16:47:32