ios iPhone:显示模式的UITableViewController与导航条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4600448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:26:29  来源:igfitidea点击:

iPhone: Show modal UITableViewController with Navigation bar

iphoneobjective-ciosuitableview

提问by Nic Hubbard

I am showing a modal view which is a UITableViewControllerclass. For some reason it won't show the navigation bar when I show it. Here is my code:

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

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

I thought it was shown by default? If it helps, I am calling this from another class that is also a UITableViewControllermanaged by a UINavigationController. Ideas?

我以为它是默认显示的?如果有帮助,我将从另一个同样UITableViewControllerUINavigationController. 想法?

回答by BoltClock

When you present a modal view controller it does not use any existing navigation controllers or navigation bars. If all you want is to display a navigation bar, you need to add the navigation bar as a subview of your modal view and present it as you're doing.

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

If you want to present a modal view controller with navigation functionality, you need to present a modal navigation controller containing your detail view controller instead, like so:

如果你想展示一个具有导航功能的模态视图控制器,你需要展示一个包含细节视图控制器的模态导航控制器,如下所示:

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

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

Your modal controller will manage its own navigation stack.

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

回答by Scott

Here is one way to display navigation bar for those who are using storyboards, suggested by Apple's Tutorial on Storyboard.

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

Because a modal view controller doesn't get added to the navigation stack, it doesn't get a navigation bar from the table view controller's navigation controller. To give the view controller a navigation bar when presented modally, embed it in its own navigation controller.

因为模态视图控制器不会被添加到导航堆栈中,所以它不会从表视图控制器的导航控制器中获得导航栏。要在以模态呈现时为视图控制器提供导航栏,请将其嵌入到其自己的导航控制器中。

  1. In the outline view, select View Controller.
  2. With the view controller selected, choose Editor > Embed In > Navigation Controller.
  1. 在大纲视图中,选择视图控制器。
  2. 选择视图控制器后,选择 Editor > Embed In > Navigation Controller。

回答by malhal

On iOS 7 and you just want a navigation bar on your modal view controller to show a title and some buttons? Try this magic in your UITableViewController:

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

回答by Stanislav Pankevich

I want to share how the accepted solution can be used in projects with storyboards:

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

The simple approach is to put in a storyboard blank navigation controller before the VC which is to be presented modally, so the relations look like:

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

(Presenter VC) -> presents modally -> (navigation controller having a controller to be presented as its root).

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

We've tried this approach for a while and noticed that our storyboards become "polluted" by a large number of such intermediate navigation controllers when each! of them is used exclusively for one! presentation of some other controller, that we want to be presented modally with navigation bar.

我们已经尝试了这种方法一段时间,并注意到我们的故事板被大量这样的中间导航控制器“污染”了!其中一个专供一个!一些其他控制器的呈现,我们希望通过导航栏以模态方式呈现。

Our current solution is to encapsulate the code from accepted answer to a custom segue:

我们当前的解决方案是将接受的答案中的代码封装到自定义转场:

#import "ModalPresentationWithNavigationBarSegue.h"

@implementation ModalPresentationWithNavigationBarSegue

- (void)perform {
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController];

    [self.sourceViewController presentViewController:navigationController animated:YES completion:nil];
}
@end

Having this segue in our project we do not create intermediate navigation controllers in our storyboards anymore, we just use this ModalPresentationWithNavigationBarSegue like:

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

Presenter VC --> Presentee VC

演示者 VC --> 演示者 VC

I hope that this answer will be helpful to people who like to avoid unnecessary duplication in their apps storyboards.

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

回答by xhan

If you only need a NavigationBar, you can add an instance of UINavigationBarand assign BarItems to it.

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

回答by Evan Stone

I just wanted to add something to what @Scott said. His answer is definitely the easiest and most accepted way of doing it now with Storyboards, iOS 7 and 8... (and soon, 9).

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

Definitely adding a view controller to the Storyboard and Embedding it as described by @Scott is the right way to go.

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

Then, just add the segue by control-dragging from the source view controller to the target (the one you want to show modally), select "Present Modally" when the little view appears with the choices for the type of segue. Probably good to give it a name too (in the example below I use "presentMyModalViewController").

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

One thing that I needed that was missing is @Scott's case is when you want to actually pass on some data to that modally-presented view controller that is embedded in the navigation controller.

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

If you grab the segue.destinationViewController, it will be a UINavigationController, not the controller you embedded in the UINavigationController.

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

So, to get at the embedded view controller inside the navigation controller, here's what I did:

因此,为了获得导航控制器内的嵌入式视图控制器,我做了以下工作:

- (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!";
    }
}

Hope this helps!

希望这可以帮助!