【问题标题】:iPhone: Show modal UITableViewController with Navigation bariPhone:显示带有导航栏的模态 UITableViewController
【发布时间】:2011-06-03 18:44:53
【问题描述】:

我正在展示一个模态视图,它是一个 UITableViewController 类。出于某种原因,当我显示它时它不会显示导航栏。这是我的代码:

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
    detailViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    detailViewController.navigationController.navigationBarHidden = NO;
    [self.navigationController presentModalViewController:detailViewController animated:YES];
    detailViewController = nil;
    [detailViewController release];

我以为它是默认显示的?如果有帮助,我会从另一个类中调用它,该类也是由UINavigationController 管理的UITableViewController。想法?

【问题讨论】:

    标签: iphone objective-c ios uitableview


    【解决方案1】:

    当您呈现模态视图控制器时,它不使用任何现有的导航控制器或导航栏。如果您只想显示导航栏,则需要将导航栏添加为模态视图的子视图,并按您的操作呈现。

    如果你想呈现一个带有导航功能的模态视图控制器,你需要呈现一个包含你的细节视图控制器的模态导航控制器,像这样:

    SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
    [detailViewController release];
    
    navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self presentModalViewController:navController animated:YES];
    [navController release];
    

    您的模态控制器将管理自己的导航堆栈。

    【讨论】:

    • 谢谢,感谢您的解释,所以我知道我做错了什么。
    • 如果您使用故事板,则完全不需要编码来完成此操作。很好的解决方案!
    • 我不知道为什么我在引入故事板后就退出了 iOS 开发。这些仍然是平台上发生的最好的事情之一。 (当然,我完全知道我为什么退出:因为我买不起。我只是说我希望故事板掉线时不会发生这种情况。)
    【解决方案2】:

    Apple's Tutorial on Storyboard 建议使用故事板的用户,这是一种显示导航栏的方法。

    因为模态视图控制器没有添加到导航堆栈中,所以它没有从表格视图控制器的导航控制器中获取导航栏。要在模态显示时为视图控制器提供导航栏,请将其嵌入到自己的导航控制器中。

    1. 在大纲视图中,选择 View Controller。
    2. 选择视图控制器后,选择编辑器 > 嵌入 > 导航控制器。

    【讨论】:

    • 确保将模态序列添加到导航控制器而不是 TableViewController
    • 在 Twitter 的编辑用户个人资料页面的情况下。这是一个模态呈现的 UITableViewController,顶部有 DONE 和 CANCEL 按钮。在这种情况下,这个答案在语义上没有意义,因为没有发生导航。
    【解决方案3】:

    在 iOS 7 上,您只希望模态视图控制器上的导航栏显示标题和一些按钮?在你的 UITableViewController 中试试这个魔法:

    // in the .h
    @property (strong) UINavigationBar* navigationBar;
    
    //in the .m
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.navigationItem.title = @"Awesome";
        self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero];
        [self.view addSubview:_navigationBar];
        [self.navigationBar pushNavigationItem:self.navigationItem animated:NO];
    }
    
    -(void)layoutNavigationBar{
        self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.tableView.frame.size.width, self.topLayoutGuide.length + 44);
        self.tableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
        //no need to call super
        [self layoutNavigationBar];
    }
    
    -(void)viewDidLayoutSubviews{
        [super viewDidLayoutSubviews];
        [self layoutNavigationBar];
    }
    

    【讨论】:

    • 接缝成为做事的好方法。但是当我在静态 UITableViewController 上尝试它时,我无法再滚动 tableview。知道为什么吗?
    • 现在最好将它嵌入到导航控制器中。
    • 这是一个不错的解决方案,但一个小问题是当您滚动时,导航栏顶部会显示单元格标题。
    • 我通过在-(void)layoutNavigationBar 末尾添加[self.view bringSubviewToFront:self.navigationBar]; 解决了这个问题。
    【解决方案4】:

    我想分享如何在带有故事板的项目中使用公认的解决方案:

    简单的方法是在要模态呈现的VC之前放置一个故事板空白导航控制器,因此关系如下:

    (Presenter VC)-> 模态呈现->(导航控制器有一个控制器作为其根呈现)。

    我们已经尝试了这种方法一段时间,并注意到我们的情节提要被大量此类中间导航控制器“污染”了!其中一个专用于一个!展示其他一些控制器,我们希望通过导航栏以模态方式展示。

    我们目前的解决方案是将代码从接受的答案封装到自定义 segue:

    #import "ModalPresentationWithNavigationBarSegue.h"
    
    @implementation ModalPresentationWithNavigationBarSegue
    
    - (void)perform {
        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController];
    
        [self.sourceViewController presentViewController:navigationController animated:YES completion:nil];
    }
    @end
    

    在我们的项目中有这个 segue,我们不再在我们的故事板中创建中间导航控制器,我们只使用这个 ModalPresentationWithNavigationBarSegue,如下所示:

    Presenter VC --> Presentee VC

    我希望这个答案对那些希望避免在应用故事板中出现不必要的重复的人有所帮助。

    【讨论】:

      【解决方案5】:

      我只是想为@Scott 所说的添加一些内容。他的回答绝对是现在使用 Storyboards、iOS 7 和 8...(很快,9)最简单和最被接受的方式。

      按照@Scott 的描述,将视图控制器添加到 Storyboard 并嵌入它是正确的方法。

      然后,只需通过从源视图控制器拖动控件到目标(您要以模态方式显示的那个)来添加转场,当小视图出现并选择转场类型时,选择“以模态方式呈现”。给它起个名字可能也不错(在下面的示例中,我使用“presentMyModalViewController”)。

      我需要但缺少的一件事是@Scott 的情况是,当您想要将一些数据实际传递给嵌入在导航控制器中的模态呈现视图控制器时。

      如果你抓取 segue.destinationViewController,它将是一个 UINavigationController,而不是你嵌入在 UINavigationController 中的控制器。

      所以,要访问导航控制器中的嵌入式视图控制器,我是这样做的:

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
          if ([segue.identifier isEqualToString:@"presentMyModalViewController"]) {
              // This could be collapsed, but it's a little easier to see
              // what's going on written out this way.
      
              // First get the destination view controller, which will be a UINavigationController
              UINavigationController *nvc = (UINavigationController *)segue.destinationViewController;
      
              // To get the view controller we're interested in, grab the navigation controller's "topViewController" property
              MyModalViewController *vc = (EmailReceiptViewController *)[nvc topViewController];
      
              // Now that we have the reference to our view controller, we can set its properties here:
              vc.myAwesomeProperty = @"awesome!";
          }
      }
      

      希望这会有所帮助!

      【讨论】:

        【解决方案6】:

        如果您只需要NavigationBar,您可以添加UINavigationBar 的实例并将BarItems 分配给它。

        【讨论】:

        • 这取决于 ViewController:我认为您不能将 UINavigationBar 添加到 UITableViewController,可以吗?
        • 在 IB 中,转到 Editor -> Embed in Navigation Controller,您将拥有一个导航栏。拖动并将 BarButtonItems 添加到其中。
        猜你喜欢
        • 2016-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-17
        • 2016-11-03
        • 1970-01-01
        相关资源
        最近更新 更多