presentViewController和显示导航栏


99

我有一个视图控制器层次结构,最顶层的控制器显示为模式,并想知道在使用时如何显示导航栏

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

“ presentViewController:animated:completion:”的文档请注意:

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

对于'modalPresentationStyle',文档说:

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

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

以前,我使用的工具'UIViewController:presentModalViewController:animated'运行良好,但是自iOS 5.0以来,该API已被弃用,因此我将切换到新的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];

Answers:


193

的确,如果您以模态方式在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:^{

                        }];

以模态显示视图时,您应该会看到一个导航栏。


那几乎就是我开始的。但是我之所以不使用'presentModalViewController'的原因是因为它被标记为已弃用的API。
乔纳斯·加德纳

这是在UIViewController类中编写的内容://将另一个视图控制器显示为模态子代。如果使用动画,则使用垂直工作表过渡。-(void)presentModalViewController:(UIViewController *)modalViewController动画:(BOOL)动画;因此只需调用新方法并传递nil即可完成操作,您应该会很好。
Manish Ahuja'3

好答案。更新为使用(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne 2014年

2
当我尝试显示导航控制器时,它崩溃了('NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported')。这怎么工作?
oarfish

就我而言,它显示为bar,但其他内容在呈现动画时放置不正确。而且只有在此动画之后,它才会跳到正确的位置。
Vyachaslav Gerchicov,2015年

46

Swift 5.*

导航:

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)

1
但是,当我尝试输入代码时如何设置,然后只能设置导航栏,但无法更改其属性(如条形颜色,标题等
。– Jaydip 17-10-9

不涉及这个问题,但你可以在这里找到答案stackoverflow.com/questions/26008536/...
塔尔锡安

23

您可以使用:

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

回想一下(我认为):

[self.navigationController popToRootViewControllerAnimated:YES];

3
谢谢,如果您的情节提要中已经有导航控制器设计,那么这是最好的方法。你帮了我很多
phyzalis

返回的是[self.navigationController popViewControllerAnimated:YES]; popToRoot-一路回到第一个viewcontroller
Boris Gafurov,

2

我在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: ^ {

    }];
}

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

迅捷3

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

如何在显示的UIViewController中添加“
后退”

1

迅捷版:提供了一个嵌入在导航控制器中的ViewController。

    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

我使用此代码。在iOS 8中运行正常。

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

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

如果您未设置modalPresentationStyle属性(如UIModalPresentationFormSheet),则导航栏将始终显示。为了确保,永远做

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

这将始终显示导航栏。


嗯..即使固定引用了“ topViewController”,我仍然看到相同的行为。我不认为我会以任何特殊方式将其他视图控制器添加到导航堆栈中。
乔纳斯·加德纳

0

如果您在Swift 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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.