ScrollView, созданный в раскадровке, инициализированный кадром 0,0,0,0

Я создал UIScrollView в раскадровке, связал его как свойство с контроллером представления и теперь пытаюсь добавить некоторые подпредставления с разбиением на страницы. Но, несмотря на то, что я установил размеры в раскадровке графически, кадр UIScrollView в конечном итоге равен 0,0,0,0. Должен ли я жестко кодировать размеры, даже если я уже указал их графически в раскадровке?

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


person user1096786    schedule 18.06.2012    source источник
comment
Как вы нарисовали UIScrollView? Вы нарисовали его на своем ViewController или в свободной форме?   -  person Justin Paulson    schedule 19.06.2012
comment
Я просто перетащил его как объект из раскадровки в ViewController.   -  person user1096786    schedule 19.06.2012
comment
Откуда вы знаете, что это 0,0,0,0? Он должен быть того же размера, что и прокрутка, которую вы перетащили в ViewController.   -  person Justin Paulson    schedule 19.06.2012
comment
Я поставил точку останова и посмотрел на нее. Кроме того, если я жестко запрограммирую новые значения для кадра, они будут обновлены до этого.   -  person user1096786    schedule 19.06.2012
comment
Вы инициализируете ScrollView в своем viewDidLoad или что-то в этом роде?   -  person Justin Paulson    schedule 19.06.2012
comment
Нет, просто перетащите его в раскадровку и подключите к свойству в моем контроллере.   -  person user1096786    schedule 19.06.2012


Ответы (5)


С раскадровками viewDidLayoutSubviews — это место, где вы можете получить размер всех ваших представлений. viewWillAppear у меня не работало и всегда возвращало (0,0,0,0);

person Ben Coffman    schedule 10.01.2013
comment
Также обратите внимание на хитрость: вы можете получить размеры содержащихся там подпредставлений, а затем добавить код макета для подпредставлений этих подпредставлений, теперь зная кадр/границы. - person John LaBarge; 10.09.2014

С раскадровками выходы контроллера не подключаются до viewDidLoad, и его размер не устанавливается до viewWillAppear, см. здесь:

http://cs193p.m2m.at/lecture-8/

Как только контроллер полностью создан и его выходы подключены, вызывается viewDidLoad:. Таким образом, это хорошее место для размещения кода установки. Однако размер контроллера еще не установлен, а установлен в viewWillAppear:, который вызывается непосредственно перед тем, как представление появится на экране.

Так что я думаю, что предложение Энрикоса правильно. Просто попробуйте поместить информацию, связанную с размером, в viewWillAppear.

person Christian Hennen    schedule 15.10.2012
comment
viewDidLayoutSubviews для раскадровки. Смотрите мой комментарий ниже. - person Ben Coffman; 10.01.2013

Я обнаружил, что когда я получаю доступ к прокрутке в viewWillAppear, фрейм на самом деле дает правильные числа. Раньше я пробовал это в awakeFromNib и viewDidLoad и также получил 0,0,0,0 кадр.

Что странно, до раскадровки вы можете получить правильные размеры кадра в awakeFromNib. Примером этого является один из примеров кода Apple PageControl.

Короче говоря, чтобы ответить на вопрос, попробуйте получить к нему доступ из viewWillAppear (при условии, что вы создали UIScrollView в раскадровке).

person Enrico Susatyo    schedule 10.10.2012
comment
Из обсуждения awakeFromNib: Каждому объекту, загруженному из архива, отправляется сообщение awakeFromNib, но только в том случае, если он может ответить на сообщение, и только после того, как все объекты в архиве будут загружены и инициализированы. Когда объект получает сообщение awakeFromNib, для него гарантированно установлены все переменные выходного экземпляра. И из того, что я тестировал, я не получаю никакой ссылки на мою розетку в этом методе. Так что, возможно, это предположение больше не соответствует действительности с раскадровкой, и документацию необходимо обновить. Хотя рамка моих розеток у меня уже установлена ​​в viewDidLoad. - person florian; 16.10.2012
comment
Извините, у меня проблема именно в том, что я просто пытаюсь перетащить UIScrollView в раскадровку, и инспектор размеров определил его размер. Однако я установил точку останова в viewWillAppear (не viewDidLoad!!), и он по-прежнему указывает, что кадр {0,0,0,0}. Хотя я могу установить его вручную, что произойдет, когда UIScrollView загрузится из раскадровки? - person Yeung; 24.10.2012
comment
Эй, я обнаружил, что могу получить доступ к правильному значению кадра в viewDidAppear. Я строю в Xcode 4.5 и для симулятора iPhone 6.0. Разве это не связано с каким-то обновлением? - person Yeung; 24.10.2012
comment
@神 貓 это в основном то, что мне было интересно. @florian считает, что в iOS 6 это работает по-другому, и документы нужно обновить. - person Enrico Susatyo; 25.10.2012
comment
Как вы сказали, решение состояло в том, чтобы использовать viewDidAppear (я использовал viewWillAppear). СПАСИБО ОГРОМНОЕ. Вы спасли меня от еще одного дня головной боли. - person NitroG42; 10.04.2013
comment
Рамка просмотра прокрутки НЕ устанавливается при вызове viewWillAppear, но устанавливается при вызове viewDidAppear. Я лично считаю это ошибкой и собираюсь отправить ее в Apple прямо сейчас. Мне нужно иметь возможность размещать свои представления до того, как они будут показаны пользователю, поэтому мне нужна эта информация в viewWILLAppear. - person Kenny Wyland; 08.08.2013
comment
@KennyWyland Пожалуйста. До iOS 6 фрейм устанавливался обоими методами, поэтому я предполагаю, что это ошибка, появившаяся в iOS 6. - person Enrico Susatyo; 08.08.2013
comment
Это не ошибка, это связано с Autolayout. Представления под AL не имеют рамок, пока не завершится проход компоновки. - person jrturton; 09.08.2013

Вероятно, вы установили точку останова в строке, где представление еще не было настроено. Попробуй это:

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        CGRect frame = self.scrollView.frame;
        NSLog (@"FRAME IS %@", NSStringFromCGRect(frame));
    }
    return self;
}
person Alex L    schedule 10.10.2012

Это очень просто: отключите Использовать автомакет в настройках раскадровки.

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

person Michael Dorner    schedule 09.08.2013