web-dev-qa-db-ja.com

UIViewControllerはUINavigationBarの下に拡張するのにUITableViewControllerは拡張しないのはなぜですか?

UITabbarControllerを含むUINavigationControllerがあります。 UIViewviewUIViewControllerとして割り当てるnavControllerのサブクラスがあります。これはかなり標準的なものですよね?これは私がそれをする方法です

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

このviewにはUITableViewsubViewとしてあります

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

デバッグのために、ビューに_self.backgroundColor = [UIColor blueColor]_を設定しています。

上記のtableViewの初期化から、ビューとテーブルのframeは同じであると考えるかもしれません。ただし、_iOS 7_で実行すると、ビューのOriginはUINavigationBarの後ろに設定されます。 UINavigationControllerのサブクラスで_self.navigationBar.translucent = YES;_を設定しているため、これは理解できます。しかし、私が理解していないのは、テーブルがnavBarのすぐ下にある理由です。 navBarの後ろにある_(0, 0)_からも開始すべきではありませんか?以下のスクリーンショット_Scenario 1_を参照してください。 navBarの背後にある青い色相に注意してください

Scenario 1

ここで、単に_[self.navigationController pushViewController.....]_を使用して、ナビゲーションスタックでPushをもう1つviewControllerします。ここでも、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);
_

したがって、上記のロジックを使用すると、ラベルが表示されるはずですよね?しかし、今回はそうではありません。今回は、ラベルはnavBarの後ろにあります。

Scenario - 2

NavBarの背後にある赤い色相に注意してください。

私は本当にサブビューをnavBarの下に一貫して配置したいと思います。私の質問は

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?_

61
unspokenblabber

既定では、UITableViewControllerのビューはiOS7で自動的に挿入されるため、ナビゲーションバー/ステータスバーの下からは開始されません。これは、Interface BuilderのUITableViewControllerの[Attributes Inspector]タブにある[Adjust scroll view insets]設定、またはsetAutomaticallyAdjustsScrollViewInsets: UIViewControllerのメソッド。

UIViewControllerのコンテンツの場合、ビューのコンテンツを上部/下部のバーの下に拡張したくない場合は、Interface Builderの[上部のバー/下部のバーの下にエッジを拡張]設定を使用できます。これは、edgesForExtendedLayoutプロパティを介してアクセスできます。

136
Greg

Objective-C:

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

スイフト2:

self.edgesForExtendedLayout = UIRectEdge.None

Swift 3+:

self.edgesForExtendedLayout = []
112
Gank

@Gankの答えは正しいですが、これを行うのに最適な場所はUINavigationControllerDelegate(ある場合)です。

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