iPhone:使用导航栏显示模态UITableViewController

时间:2011-01-05 02:56:56

标签: iphone objective-c ios uitableview

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

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

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

6 个答案:

答案 0 :(得分:144)

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

如果要呈现具有导航功能的模态视图控制器,则需要提供包含详细视图控制器的模态导航控制器,如下所示:

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[detailViewController release];

navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:YES];
[navController release];

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

答案 1 :(得分:36)

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

由于模态视图控制器未添加到导航堆栈,因此它不会从表视图控制器的导航控制器中获取导航栏。在以模态方式呈现时为视图控制器提供导航栏,将其嵌入到自己的导航控制器中。

  1. 在大纲视图中,选择“查看控制器”。
  2. 选择视图控制器,选择编辑器>嵌入>导航控制器。

答案 2 :(得分:17)

在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];
}

答案 3 :(得分:7)

我想分享一下如何在带有故事板的项目中使用已接受的解决方案:

简单的方法是在VC之前放入一个故事板空白导航控制器,它将以模态方式呈现,因此关系看起来像:

  

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

我们已经尝试了这种方法一段时间,并注意到我们的故事板已经被污染了#34;每个人都有大量这样的中间导航控制器!它们专门用于一个!介绍一些其他控制器,我们希望用导航栏以模态方式呈现。

我们当前的解决方案是将接受答案的代码封装到自定义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 - >出席前VC

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

答案 4 :(得分:5)

如果您只需要NavigationBar,则可以添加UINavigationBar的实例并为其指定BarItem。

答案 5 :(得分:5)

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

绝对将视图控制器添加到故事板并按照@Scott的描述嵌入它是正确的方法。

然后,只需通过控制拖动从源视图控制器添加segue到目标(您想要以模态方式显示的目标),当出现小视图时选择“存在模式”,并选择segue类型。可能也很好给它一个名字(在下面的例子中我使用“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!";
    }
}

希望这有帮助!