Как получить кадры подвидов на ранней стадии процесса инициализации

Я меняю код с XIB на раскадровку. Кажется, существует существенная разница во времени установки границ кадра для подвидов сцены раскадровки.

Техника, которую часто использует этот код, такова:

  • подпредставление UIView имеет размеры, определенные в XIB или файле раскадровки (что позволяет кому-то, кроме программиста, изменять пользовательский интерфейс)
  • UIViewController имеет ссылку на объект как IBObject UIView *
  • в - viewWillAppear() UIViewController выполняются определенные вычисления, и на основе этих вычислений выполняется рисование.

Например, в нашем файле XIB или Storyboard есть UIView, который мы хотим разделить на четыре области. Контроллер смотрит на границы этого UIView, смотрит на его фрейм, а затем в UIView рисует четыре прямоугольника, каждый в четверть размера.

In .h:

IBOutlet UIView *outputColorKeyView;

In .m's viewWillAppear:

CGRect keyBounds = [outputColorKeyView bounds];

float high = keyBounds.size.height;
float wide = keyBounds.size.width;

float cellWidth = wide/4.0;

XLog(@"Dimensions for the color key are: %f %f", high, wide);

Моя проблема в том, что в XIB это работало нормально: я смог увидеть, что размеры области, которую я должен был нарисовать, были шириной 200 точек (например), а ячейки могли быть нарисованы шириной 50 точек.

В раскадровках это больше не работает для меня: я получаю кадр (0,0,0,0), когда я звоню из метода viewWillAppear контроллера:

[18:09:16.901|4096] Dimensions for the color key are: 0.000000 0.000000

Однако при запуске с более позднего этапа жизненного цикла программы (запускается кнопкой) я получаю правильный результат:

[18:09:35.812|4096] Dimensions for the color key are: 36.000000 734.000000

Есть ли способ получить эту информацию до появления представления? Я бы так подумал, но viewWillAppear кажется последней возможностью перед тем, как представления будут фактически отображены. Или есть какой-то очевидный переключатель, который я упустил, который заставит эту технику работать так, как задумано?

Спасибо


person Todd Masco    schedule 15.11.2012    source источник
comment
Там происходит что-то еще. Если IBOutlet подключен правильно и представление является правильным подпредставлением свойства view контроллера представления, то оно должно быть доступно уже в viewDidLoad:... то есть до viewWillAppear:.   -  person Phillip Mills    schedule 15.11.2012
comment
Хорошо, спасибо - это приятно знать. Код добавлен прямо из версии XIB, поэтому кажется, что он должен работать идентично, но тот факт, что размеры недоступны из viewWillAppear, но недоступны позже (без манипуляции с представлением другим другим методом), заставил меня интересный.   -  person Todd Masco    schedule 15.11.2012
comment
Моя главная мысль заключалась в том, может ли быть параметр UIView в раскадровке, который неочевидно имеет этот тонкий побочный эффект. Я попытаюсь продублировать проблему в каком-нибудь свежем коде.   -  person Todd Masco    schedule 15.11.2012
comment
ОК, у меня такое же поведение от совершенно свежего проекта, пустой раскадровки (это вторая сцена, связанная одной кнопкой с переходом режима).   -  person Todd Masco    schedule 16.11.2012
comment
Пустая раскадровка за исключением двух сцен (это вторая сцена, соединенная одной кнопкой с переходом режима). Вторая сцена — это один UIView. Когда я делаю это в viewDidLoad контроллера сцены: - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"---------------------------"); NSLog(@"viewDidLoad[TestGameController]: my view is: %@", [self view]); NSLog(@"viewDidLoad[TestGameController]: my subview1 is: %@", subViewOne); }   -  person Todd Masco    schedule 16.11.2012
comment
Я получаю: 2012-11-15 14:38:03.801 testStoryBoardSubViews[10666:c07] viewDidLoad[TestGameController]: мое представление: ‹UIView: 0x10019910; кадр = (0 20; 768 1004); авторазмер = RM+BM; layer = ‹CALayer: 0x10019970›› 2012-11-15 14:38:03.801 testStoryBoardSubViews[10666:c07] viewDidLoad[TestGameController]: мой subview1: ‹UIView: 0x10019760; кадр = (0 0; 0 0); автоматическое изменение размера = TM+BM; слой = ‹CALayer: 0x100197c0››   -  person Todd Masco    schedule 16.11.2012


Ответы (1)


Ответ был дан в ответе на мой дополнительный вопрос... место для выполнения этот материал после того, как макет сделан, в viewDidLayoutSubviews

Мне непонятно, почему информация изменилась: данные в исходном файле описания (будь то XIB или Storyboard) были доступны еще viewDidLoad до настоящего времени (0,0,0,0), но это разница, о которой следует помнить, если вы следуете большому количеству кода учебников в книгах и в сети.

person Todd Masco    schedule 16.11.2012
comment
Я думаю, что обнаружил, что ключевым элементом в уравнении является то, включен ли Autolayout для xib/storyboard. Без Autolayout рамки, установленные в IB, используются для установки размеров представления в иерархии во время загрузки. Когда Autolayout включен, изменение размера откладывается до макета подвида (как вы упоминали выше). - person Phillip Mills; 16.11.2012