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

我有UITabbarControllerUINavigationController在里面。 我有一个UIView的子类,我分配为navControllerUIViewControllernavController 。 这是非常标准的东西,对吧? 这是我如何做到的

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

这个view有一个UITableView作为子subView

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

为了debugging的目的,我在视图上设置了self.backgroundColor = [UIColor blueColor]

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

情况1

现在,我只需使用[self.navigationController pushViewController.....][self.navigationController pushViewController.....]导航堆栈上的另一个viewController 。 再次我有一个自定义的UIView与在其中的tableView 。 不过,我也有这个表上面的UILabel ,再次debugging,我给了它一个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); 

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

情景 -  2

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

我真的想一直alignmentnavBar下面的子视图。 我的问题是

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?

默认情况下,UITableViewController的视图会在iOS7中自动插入,以便它们不会在导航栏/状态栏下面启动。 这是通过Interface Builder中UITableViewController的Attributes Inspector选项卡上的“Adjust scroll view insets”设置,或通过UIViewController的setAutomaticallyAdjustsScrollViewInsets:方法设置的setAutomaticallyAdjustsScrollViewInsets:

对于UIViewController的内容,如果不希望其视图的内容在顶部/底部条形图下扩展,则可以使用界面构build器中的“顶部条形图下的边线下/底部条形图”设置。 这可以通过edgesForExtendedLayout属性进行访问。

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

Swift 2:

 self.edgesForExtendedLayout = UIRectEdge.None 

Swift 3:

 self.edgesForExtendedLayout = [] 

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

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