#ios #uiviewcontroller #frame
#iOS #uiviewcontroller #кадр
Вопрос:
У меня есть простой 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. Это тоже не имеет смысла. В моем случае у меня действительно есть панель вкладок, поэтому высота не должна быть минус строка состояния, минус панель uinavigationbar и минус высота панели вкладок?
Спасибо
Комментарии:
1. поскольку высота строки состояния 20 пикселей
Ответ №1:
Фрейм UIView принимает допустимые аргументы только при вызове -viewWillAppear
, -viewDidAppear
методов. Вы не должны полагаться на frame и выполнять какие-либо вычисления, используя его раньше.
Также вам не следует использовать view
свойство UIViewController (UITableViewController) (из других объектов) перед вызовом -viewDidLoad
метода, поэтому вам не следует использовать view и добавлять к нему какие-либо контроллеры в init
методе, только в -loadView
или (лучше) в -viewDidLoad
. Добавьте свой вложенный просмотр в эти методы и установите его рамку перед отображением.
В режиме жизненного цикла ViewController представление может загружаться и выгружаться много раз (например, didReceiveMemoryWarning выгружает представление), представление вообще никогда не может загружаться.
Ответ №2:
Вы смешиваете две разные системы координат. рамка 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).
Комментарии:
1. Да, спасибо. И действительно, именно так это задокументировано в документах Apple iOS для разработчиков: ссылка на класс UIView > Свойства> «границы» и «рамка».