Подтвердить что ты не робот

Почему UIViewController распространяется под UINavigationBar, а UITableViewController - нет?

У меня UITabbarController с UINavigationController в нем. У меня есть подкласс UIView, который я назначаю как view of UIViewController в navController. Это довольно стандартный материал, не так ли? Вот как я это делаю

_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];

Для отладки я устанавливаю self.backgroundColor = [UIColor blueColor] в представлении.

Из приведенной выше инициализации tableView можно подумать, что представление и таблица frame совпадают. Однако, когда я запускаю в iOS 7, начало представления устанавливается за UINavigationBar. Это понятно, потому что я устанавливаю self.navigationBar.translucent = YES; в свой подкласс UINavigationController. Но что я не понимаю, так это то, как стол сидит чуть ниже navBar? Разве он не должен начинаться с (0, 0), который находится за navBar? См. Снимок экрана Scenario 1 ниже. Обратите внимание на синий оттенок за navBar

Scenario 1

Теперь я 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);

Итак, перейдя по логике выше, ярлык должен быть видимым, не так ли? Но на этот раз это не так. На этот раз метка находится за navBar.

Scenario - 2

Обратите внимание, красный оттенок позади navBar.

Мне бы очень хотелось выровнять subView под navBar последовательно. Мои вопросы

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

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

4b9b3361

Ответ 1

По умолчанию представления UITableViewController автоматически вставляются в iOS7, чтобы они не запускались под панелью навигации/панель состояния. Это контроллер с помощью параметра "Настроить параметры просмотра прокрутки" на вкладке "Инспектор атрибутов" в UITableViewController в построителе интерфейса или методом setAutomaticallyAdjustsScrollViewInsets: UIViewController.

Для содержимого UIViewController, если вы не хотите, чтобы его содержимое представления расширялось под верхними/нижними столбцами, вы можете использовать настройки "Расширить границы в верхних барах/нижних границах" в "Интерфейс-Builder". Это доступно с помощью свойства edgesForExtendedLayout.

Ответ 2

Objective-C:

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

Свифт 2:

self.edgesForExtendedLayout = UIRectEdge.None

Свифт 3+:

self.edgesForExtendedLayout = []

Ответ 3

Ответ на @Gank правильный, но лучше всего сделать это на UINavigationControllerDelegate (если он у вас есть):

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