Посмотреть рамка между viewWillAppear и viewDidAppear:


я обнаружил странное поведение в моем приложении, где подключен IBOutlet имеет кадр подключенного представления между вызовами в моем контроллере представления в viewWillAppear: и viewDidAppear:. Вот соответствующий код в моем UIViewController подкласс:

-(void)viewWillAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

-(void)viewDidAppear:(BOOL)animated {
    NSLog(@"%@", self.scrollView);
}

и полученный лог:

MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>

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

4 73

4 ответа:

Autolayout сделал огромное изменение в том, как мы проектируем и разрабатываем графический интерфейс наших взглядов. Одним из главных отличий является то, что autolayout не изменяет наши размеры представления сразу, но только когда срабатывает, что означает в определенное время, но мы можем заставить его немедленно пересчитать наши ограничения или пометить их как "нуждающиеся" в макете. Он работает как -setNeedDisplay.
Большой проблемой для меня было понять и принять, что мы не должны больше пользоваться функциями автоматического изменения маски и рамки станьте бесполезным свойством в размещении наших взглядов. Нам больше не нужно думать о положении зрения, но мы должны думать, как мы хотим видеть их в пространстве, связанном друг с другом.
Когда мы хотим смешивайте старые функциями автоматического изменения маски и Autolayout, когда возникают проблемы. Мы должны подумать о реализации autolayout очень скоро и попытаться избежать смешивания старого подхода в иерархии представлений, основанной на autolayout.
Это нормально иметь вид контейнера, который использует только функциями автоматического изменения маски, например основной вид контроллера вида, но лучше, если мы не будем пытаться смешивать.
Я никогда не использовал раскадровку, но скорее всего это правильно. Используя Autolayout, рамки ваших представлений устанавливаются, когда механизм autolayout начинает свой расчет. Попробуйте спросить то же самое сразу после супер - (void)viewDidLayoutSubviews метод контроллера представления.
этот метод вызывается, когда механизм автозапуска закончил вычислять фреймы ваших представлений.

С документы:

viewWillAppear:

уведомляет контроллер представления о том, что его представление будет добавлено в иерархию представлений.

viewDidAppear:

уведомляет контроллер представления о том, что его представление было добавлено в иерархию представлений.

в результате фреймы подвидов еще не установлены в viewWillAppear:

соответствующий метод измените пользовательский интерфейс перед представлением экран - это:

viewDidLayoutSubviews

уведомляет контроллер вида, что его вид только что выложил свои подвиды.

вызов

self.представление ScrollView.layoutIfNeeded()

в своем viewWillAppear метод. После этого вы можете получить доступ к его кадр и он будет иметь то же значение, как вы печатаете в viewDidAppear

в моем случае перемещение всех методов, связанных с кадром, в

override func viewWillLayoutSubviews()

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