54

我正在使用 Xcode 4.6.1 在 Objective-C 上进行编码。我想知道当我在两个视图控制器之间创建模态转场时如何保持导航栏显示,因为我正在情节提要中进行转场,当我运行应用程序时,第二个视图控制器的导航栏消失了,并且我在那个栏上有一个完成按钮,但我看不到它。

4

11 回答 11

89

只需将另一个添加Navigation Controller到您的模态视图控制器。按照步骤

  1. 选择Modal View Controller
  2. Editor menu
  3. 选择Embed In
  4. 选择Navigation Controller

运行应用程序。现在它应该可以完美运行了。

希望这能解决您的问题。

于 2013-06-20T05:21:56.623 回答
64

Modal segues 占据了整个屏幕,因此呈现控制器中的任何导航栏、工具栏或选项卡栏都将被覆盖。如果您想在此模态控制器上添加一个导航栏,则需要专门为其添加一个导航栏,并将您想要的任何按钮添加到该新导航栏(或工具栏)。如果您不想这样做,请不要以模态方式呈现它,而是推动它。

于 2013-03-28T18:28:10.787 回答
19

您可以简单地执行以下操作来显示导航栏:

Objective-C

UINavigationController alloc]initWithRootViewController:modalVC];

斯威夫特 3

let modelVC = self.storyboard?.instantiateViewController(withIdentifier: "modalVC") as! ModalVC
let navBarOnModal: UINavigationController = UINavigationController(rootViewController: modalVC)
self.present(navBarOnModal, animated: true, completion: nil)

这将显示带有导航栏的模态视图控制器。对Objective-C的了解有限,所以介绍部分我没有写。你应该能够弄清楚这一点。;)

希望这可以帮助!

于 2017-01-22T13:29:31.310 回答
10

在 iOS 8 中有一个更好的方法。您可以使用自适应演示样式:

  1. 使用“Present as popover”转场
  2. 设置你的控制器采用 UIPopoverPresentationControllerDelegate 协议
  3. 实现2个方法

目标-C:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationFullScreen;
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style {
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: controller.presentedViewController];
    return navController;
}

迅速:

UIPopoverPresentationControllerDelegate
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.FullScreen
    }

func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    var navController = UINavigationController(rootViewController: controller.presentedViewController)
    return navController
}

斯威夫特 4:

extension MyViewController: UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.fullScreen
    }

    func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
        return UINavigationController(rootViewController: controller.presentedViewController)
    }
}

在准备 segue 方法时设置委托:

   override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if let adpostVC = segue.destinationViewController as? XXXController {
            let popPC = adpostVC.popoverPresentationController
            popPC?.delegate = self
于 2014-12-06T13:26:12.517 回答
6

快速版本:

遵循以下步骤:

  1. 在 NavigationController 中嵌入 VC
  2. 覆盖 prepareForSegue()

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      if segue.identifier == "goToYourController" {
        let navigation: UINavigationController = segue.destinationViewController as! UINavigationController
    
        var vc = YourViewController.init()
        vc = navigation.viewControllers[0] as! YourViewController
        //if you need send something to destnation View Controller 
        //vc.delegate = self
      }
    }
    
于 2016-05-13T12:23:04.807 回答
4

有一种更简单的方法可以做到这一点。正如之前的评论所说(但没有解释所有步骤),您需要将所需的目标视图控制器嵌入到导航控制器中,然后将目标视图控制器设置为导航控制器,然后导航控制器调用目标视图控制器。

首先,将 VC 嵌入到 NavVC 中。然后,您必须编写代码将 segue 目的地设置为 Nav VC。

代码如下所示:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UINavigationController *nav = segue.destinationViewController;
    AddTriviaVC *triv = [[AddTriviaVC alloc]init];
    triv = nav.viewControllers[0]; 
    triv.location = self.location; 
} 

我希望这是有道理的。

于 2014-07-16T03:06:34.950 回答
3

那可能是因为您的模态中没有 a UINavigationController。您应该使用一个(或者只是在 Storyboard 中的 ViewController 中添加一个导航栏),并以模态方式呈现。

于 2013-03-28T18:28:19.240 回答
3

为了在模态视图控制器上显示导航栏,一种方法是插入导航控制器。您将此导航控制器的 segue 设置为“以模态方式呈现”,并且可以根据需要将演示文稿设置为“全屏”。

这是它在 Interface Builder 中的样子,注意“标题”和“项目”按钮现在将显示我们已经插入了一个导航控制器作为我们的 segue 的目标。

在此处输入图像描述

于 2019-11-17T04:53:07.567 回答
1

您可以通过执行以下操作以编程方式添加工具栏-(void)viewDidLoad

NSInteger tbHeight = 50;
tb = [[UIToolbar alloc] initWithFrame:CGRectMake(0, (self.view.frame.size.height - tbHeight), self.view.frame.size.width, tbHeight)];
tb.translucent = YES;
emailButton = [[UIBarButtonItem alloc] initWithTitle:@"Email Results" style:UIBarButtonItemStyleBordered target:tvController action:@selector(actionSheet:)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(doneButtonPressed:)];

NSArray *barButton  =   [[NSArray alloc] initWithObjects:emailButton,flexibleSpace,doneButton,nil];
[tb setItems:barButton];


[self.view addSubview:tb];

barButton = nil;

然后,您必须创建一个 IBAction 来按下完成按钮,它的完成方式如下:

-(IBAction)doneButtonPressed:(id)sender {
    [self dismissModalViewControllerAnimated:YES];
}

这应该给你你想要的模式视图控制器。

于 2013-03-28T18:33:23.570 回答
1

这是我在 Swift 4.2 中的“Volodymyr Nazarkevych”的简短版本

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)
    switch(segue.identifier ?? "") {

    case "segueIdentifier": // name of your segue
        let navigation: UINavigationController = segue.destination as! UINavigationController

        //here you create new name of your destination ViewController and assign his name to let constant above
        guard let myNewViewController = navigation.viewControllers[0] as? DestinationViewController
       //DestinationViewController is your 2-ViewController where you go to from first one.

       else {
            fatalError("Unexpected destination: \(segue.destination)")
        }
       // TO DO SOMETHING HERE

   default:
        fatalError("Unexpected Segue Identifier; \(String(describing: segue.identifier))")
    }
}

“Volodymyr Nazarkevych”的代码完美运行,但仅当您的 segue 从 1-ViewController 到 2-ViewController 的 NavigationController,而不是直接到 2-ViewController 时。非常感谢!

同样在目标块代码之后的切换案例中,您可以做不同的事情,例如从第二个 ViewController 获取一些信息或文件。

于 2019-02-15T22:30:03.997 回答
0

在 storyboard 中,你应该添加一个Navigation Item到你的新 viewController,然后为你的 done 按钮添加Bar Button Item

于 2018-01-06T06:45:26.417 回答