Выяснение initWithFrame: self.view.frame 20 пикселей (строка состояния) раз и навсегда - PullRequest
5 голосов
/ 12 ноября 2011

У меня есть простой UINavigationController.В методе init я создаю и добавляю UITableView в качестве подпредставления.

- (id)init {
    self = [super init];
    if (self) {
        NSLog(@"%@", NSStringFromCGRect(self.view.frame)); // {{0, 20}, {320, 460}}
        tableView = [[UITableView alloc] initWithFrame:self.view.frame];
        [self.view addSubview:tableView];
    }
    return self;
}

Я всегда сталкиваюсь с одной и той же раздражающей проблемой при работе с новыми проектами.Добавленные подпредставления заканчиваются на 20 пикселей ниже навигационной панели.

Почему я получаю {{0, 20}, {320, 460}} для self.view.frame?Я не хочу форсировать фрейм CGRect, я бы предпочел установить его на основе фрейма контроллера представления, чтобы не сталкиваться с проблемами с динамическими изменениями фрейма (модем, телефонный звонок и т. Д., Когда строка состояния выше).

Обновление: Также заметил, что я получаю 460 высоту для кадра.Это тоже не имеет смысла.В моем случае у меня фактически есть панель вкладок, поэтому высота не должна быть минус строка состояния, минус панель навигации и минус высота панели вкладок?

Спасибо

Ответы [ 2 ]

7 голосов
/ 12 ноября 2011

Кадр UIView принимает допустимые аргументы только при вызове методов -viewWillAppear, -viewDidAppear.Вы НЕ должны полагаться на фрейм и делать какие-либо вычисления, используя его ранее.
Также вы НЕ должны использовать (из других объектов) view свойство UIViewController (UItableViewController) до вызова метода -viewDidLoad, поэтому вы не должны использовать представлениеи добавить любые контроллеры к нему в методе init, только в -loadView или (лучше) в -viewDidLoad.Добавьте ваше подпредставление в этих методах и установите его фрейм до появления.
В представлении жизненного цикла viewController можно многократно загружать и выгружать (например, didReceiveMemoryWarning unloads view), представление никогда не может загружаться вообще.

2 голосов
/ 12 ноября 2011

Вы смешиваете две разные системы координат. Кадр self.view определен в системе координат окна (или каков его родительский вид). Рамка tableView определяется в системе координат self.view.

Если вы хотите, чтобы что-то заполнило весь вид, установите

subView.frame = parentView.bounds;

границы определены в собственной системе координат представления. рамка определяется в системе координат родительского представления. Таким образом, subView.frame и parentView.bounds - это одна и та же система координат.

Когда вы устанавливаете subview.frame = parentView.frame, они перестают быть тем же самым, более чем 20 грамм = 20 унций. Основной вид имеет происхождение в (0, 20); подпредставление имеет начало в (0, 20), но в другой системе координат. В системе координат окна это (0, 40).

...