ios 为什么 UIViewController 在 UINavigationBar 下扩展,而 UITableViewController 没有?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19143353/
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-31 01:58:58  来源:igfitidea点击:

Why does UIViewController extend under UINavigationBar, while UITableViewController doesn't?

iosobjective-clayoutuiviewios7

提问by unspokenblabber

I have UITabbarControllerwith UINavigationControllerin it. I have a subclass of UIViewthat I assign as the viewof UIViewControllerin the navController. This is pretty standard stuff, right? This is how I do it

UITabbarControllerUINavigationController它。我有一个子类UIView,我分配的viewUIViewControllernavController。这是很标准的东西,对吧?这就是我的做法

_productCategoryView = [[ProductCategoryView alloc] initWithFrame:self.view.frame];
self.view = _productCategoryView;

This viewhas a UITableViewas subView

view有一个UITableView作为subView

_productCategoryTableView = [[UITableView alloc] initWithFrame:self.frame style:UITableViewStylePlain];
_productCategoryTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_productCategoryTableView.backgroundColor = [UIColor clearColor];
[self addSubview:_productCategoryTableView];

For the sake of debugging I am setting self.backgroundColor = [UIColor blueColor]on the view.

为了调试,我self.backgroundColor = [UIColor blueColor]在视图上设置。

From the above initialization of tableViewone might think that the view's and table's frameis same. However when I run in iOS 7, the view's origin is set behind the UINavigationBar. This is understandable because I am setting self.navigationBar.translucent = YES;in my subclass of UINavigationController. But what I don't understand is how come the table is sitting just below the navBar? Shouldn't it also start from (0, 0)which is behind the navBar? See screenshot Scenario 1below. Notice the blue hue behind navBar

从上面的初始化tableView可能会认为视图和表frame是一样的。但是,当我运行时iOS 7,视图的原点设置在UINavigationBar. 这是可以理解的,因为我self.navigationBar.translucent = YES;在我的UINavigationController. 但我不明白的是桌子怎么就坐在下面navBar?它不应该也从(0, 0)后面的哪个开始navBar?请参阅Scenario 1下面的屏幕截图。注意背后的蓝色调navBar

Scenario 1

场景一

Now, I pushanother viewControlleron the navigation stack, simply by using [self.navigationController pushViewController.....]. Again I have a custom UIViewwith a tableViewin it. However I also have a UILabelabove this table, and again for debugging, I gave it a redColor. This time I am setting the label's originto be almost same as the view's

现在,我push另一个viewController在导航堆栈上,只需使用[self.navigationController pushViewController.....]. 我有一个习惯,里面UIView有一个tableView。但是我UILabel在这张表上面也有一个,再次为了调试,我给了它一个redColor. 这次我将标签设置origin为与视图几乎相同

CGRect boundsInset = UIEdgeInsetsInsetRect(self.bounds, UIEdgeInsetsMake(10, 10, 10, 10));

CGSize textSize = [_titleLabel.text sizeWithFont:_titleLabel.font
                               constrainedToSize:CGSizeMake(boundsInset.size.width, MAXFLOAT)
                                   lineBreakMode:NSLineBreakByWordWrapping];
printSize(textSize);
_titleLabel.frame = CGRectMake(boundsInset.origin.x,
                               boundsInset.origin.y,
                               boundsInset.size.width,
                               textSize.height);

So, going by the logic above, the label should be visible, right? But this time it's not. This time the label is behind the navBar.

所以,按照上面的逻辑,标签应该是可见的,对吧?但这次不是。这次标签在navBar.

Scenario - 2

场景 - 2

Notice, the red hue behind navBar.

请注意,navBar 后面的红色调。

I would really like to align the subView below the navBar consistently. My questions are

我真的很想一致地对齐导航栏下方的子视图。我的问题是

1. How is the tableView offset by 64pixels (height of nav + status bar in iOS 7) automatically, even though it's frame is same as the view's?

1. How is the tableView offset by 64pixels (height of nav + status bar in iOS 7) automatically, even though it's frame is same as the view's?

2. Why does that not happen in the second view?

2. Why does that not happen in the second view?

回答by Greg

By default, UITableViewController's views are automatically inset in iOS7 so that they don't start below the navigation bar/status bar. This is controller by the "Adjust scroll view insets" setting on the Attributes Inspector tab of the UITableViewController in Interface Builder, or by the setAutomaticallyAdjustsScrollViewInsets:method of UIViewController.

默认情况下,UITableViewController 的视图会自动插入到 iOS7 中,因此它们不会从导航栏/状态栏下方开始。这是通过 Interface Builder 中 UITableViewController 的 Attributes Inspector 选项卡上的“调整滚动视图插入”设置的控制器,或者通过setAutomaticallyAdjustsScrollViewInsets:UIViewController的方法。

For a UIViewController's contents, if you don't want its view's contents to extend under the top/bottom bars, you can use the Extend Edges Under Top Bars/Under Bottom Bars settings in Interface Builder. This is accessible via the edgesForExtendedLayoutproperty.

对于 UIViewController 的内容,如果您不希望其视图的内容扩展到顶部/底部栏下方,则可以使用 Interface Builder 中的 Extend Edges Under Top Bars/Under Bottom Bars 设置。这可以通过edgesForExtendedLayout酒店访问。

回答by Gank

Objective-C:

目标-C:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.edgesForExtendedLayout = UIRectEdgeNone;
 }

Swift 2:

斯威夫特 2:

self.edgesForExtendedLayout = UIRectEdge.None

Swift 3+:

斯威夫特 3+:

self.edgesForExtendedLayout = []

回答by Dan Rosenstark

@Gank's answer is correct, but the best place to do this is on the UINavigationControllerDelegate(if you have one):

@Gank 的答案是正确的,但最好的地方是UINavigationControllerDelegate(如果你有的话):

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    viewController.edgesForExtendedLayout = UIRectEdge.None
}