【问题标题】:Modal segue, navigation bar disappears模态segue,导航栏消失
【发布时间】:2013-03-19 07:53:59
【问题描述】:

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

【问题讨论】:

    标签: ios objective-c xcode4.6


    【解决方案1】:

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

    【讨论】:

    • 是的,但是在 iOS 7 中,如果您以这种方式将 NavigationBar 添加到视图中,您将不会获得单个合并的 navigationBar 和状态栏。最好使用 UINavigationController,如下所述。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您可以通过在-(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];
      }
      

      这应该可以为您提供您想要的模态视图控制器。

      【讨论】:

      • 为什么这个被减去了?该代码对于将工具栏添加到 OP 想要的模态视图控制器是正确的。我在这里错过了什么?
      • 我也不明白这个解决方案怎么错了?如果有人反对它会介意解释......
      • 问题是关于导航栏(带标题的顶部栏)而不是工具栏(底部栏)
      【解决方案4】:

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

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

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

      希望这能解决您的问题。

      【讨论】:

      • 感谢,如果您需要使用 NavigationBar 和按钮以模态方式显示一些 VC(但不想在导航堆栈中使用后退按钮看到它),它真的很有帮助。只需将您的模态 VC 嵌入到导航中,最后一个将为用户隐藏
      • 虽然不喜欢有多余的屏幕(导航控制器)只是为了显示一些顶部工具栏的想法。
      • 有关如何在 prepareToSeque 中引用 viewController (rootViewController) 的详细信息,请参阅下面的 user3634990 的答案。
      • 返回时如何移除这个navigationController?
      • 有人可以向我解释在较低级别发生了什么吗?当我们对嵌入了 Nav Controller 的 VC 执行 push segue 时,这意味着什么?
      【解决方案5】:

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

      首先,将 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; 
      } 
      

      我希望这是有道理的。

      【讨论】:

      • 这行AddTriviaVC *triv = [[AddTriviaVC alloc]init];不是死店吗?
      【解决方案6】:

      在 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
      

      【讨论】:

      • 如果没有为故事板中的 segue 分配锚点,我无法让它工作(也许这是第 1 步的隐含部分?)。但由于我从 UITextView 的编辑菜单选项中选择锚点并没有真正意义。想法?至少在某些情况下,模态表示似乎是一种更好的方法。
      【解决方案7】:

      快速版本:

      按照步骤:

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

      【讨论】:

        【解决方案8】:

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

        Objective-C

        UINavigationController alloc]initWithRootViewController:modalVC];
        

        SWIFT 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的了解有限,所以介绍部分我没有写。你应该能够弄清楚这一点。 ;)

        希望这会有所帮助!

        【讨论】:

        • 当您出于某种原因不想更改情节提要的结构(遗留代码)时,这非常有用。无论如何,这真的很棒。发送!
        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          这是我在 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 获取一些信息或文件。

          【讨论】:

            【解决方案11】:

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-02-04
              • 2016-04-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-07-25
              • 1970-01-01
              相关资源
              最近更新 更多