Я пишу приложение, и мне нужно изменить представление, если пользователь смотрит на приложение во время разговора по телефону.
Я реализовал следующий метод:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Но он не вызывается, когда приложение возвращается на передний план.
Я знаю, что могу реализовать:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
но я не хочу этого делать Я бы предпочел поместить всю информацию о макете в метод viewWillAppear: и позволить этому обрабатывать все возможные сценарии.
Я даже пытался вызвать viewWillAppear: из applicationWillEnterForeground:, но я не могу точно определить, какой контроллер представления является текущим в этой точке.
Кто-нибудь знает правильный способ справиться с этим? Я уверен, что мне не хватает очевидного решения.
ios
objective-c
iphone
viewwillappear
Филип Уолтон
источник
источник
applicationWillEnterForeground:
чтобы определить, когда ваше приложение снова вошло в активное состояние.isMemberOfClass
илиisKindOfClass
, в зависимости от ваших потребностей.Ответы:
Этот метод
viewWillAppear
следует использовать в контексте того, что происходит в вашем собственном приложении, а не в контексте размещения вашего приложения на переднем плане, когда вы переключаетесь на него из другого приложения.Другими словами, если кто-то смотрит на другое приложение или принимает телефонный звонок, затем переключается обратно на ваше приложение, которое ранее было на фоновом режиме, ваш UIViewController, который уже был виден, когда вы выходили из приложения, так сказать, «не волнует» - что касается его, он никогда не исчезает и все еще виден - и поэтому
viewWillAppear
не называется.Я рекомендую не называть
viewWillAppear
себя - это имеет особое значение, которое вы не должны подрывать! Рефакторинг, который вы можете сделать для достижения того же эффекта, может быть следующим:Затем также вы вызываете
doMyLayoutStuff
из соответствующего уведомления:Там нет никакого способа, чтобы сказать, какой «текущий» UIViewController кстати. Но вы можете найти способы обойти это, например, есть методы делегата UINavigationController, чтобы узнать, когда там представлен UIViewController. Вы можете использовать такую вещь, чтобы отслеживать последний UIViewController, который был представлен.
Обновить
Если вы размещаете пользовательский интерфейс с соответствующими масками автоматического изменения размера для различных битов, иногда вам даже не нужно иметь дело с «ручной» раскладкой вашего пользовательского интерфейса - с этим просто справляются ...
источник
self.navigationController.topViewController
эффективно обеспечивает его, или, по крайней мере, тот, который находится на вершине стека, который был бы текущий, если этот код запускает основной поток в контроллере представления. (Могу ошибаться, не играл с этим много, но, кажется, работает.)appDelegate.rootViewController
тоже сработает, но может вернутьUINavigationController
, и тогда вам понадобится,.topViewController
как говорит @MatthewFrederick.стриж
Короткий ответ
Используйте
NotificationCenter
наблюдателя, а неviewWillAppear
.Длинный ответ
Чтобы узнать, когда приложение возвращается из фона, используйте
NotificationCenter
наблюдателя, а неviewWillAppear
. Вот пример проекта, который показывает, какие события происходят когда. (Это адаптация этого ответа Objective-C .)При первом запуске приложения порядок вывода:
После нажатия кнопки «Домой» и возвращения приложения на передний план, порядок вывода будет следующим:
Так что, если вы изначально пытались использовать,
viewWillAppear
тоUIApplication.willEnterForegroundNotification
, вероятно, то, что вы хотите.Заметка
Начиная с iOS 9 и более поздних вам не нужно удалять наблюдателя. В документации говорится:
источник
Используйте Центр уведомлений в
viewDidLoad:
методе вашего ViewController для вызова метода и оттуда делайте то, что вы должны были делать в своемviewWillAppear:
методе. ЗвонокviewWillAppear:
напрямую не является хорошим вариантом.источник
dealloc
Тогда может быть хорошей идеей удалить наблюдателя в методе.viewWillAppear:animated:
На мой взгляд, один из самых запутанных методов в iOS SDK никогда не используется в такой ситуации, т. е. переключение приложений. Этот метод вызывается только в соответствии с отношением между представлением контроллера представления и окном приложения , то есть сообщение отправляется в контроллер представления, только если его представление появляется в окне приложения, а не на экране.Когда ваше приложение переходит в фоновый режим, очевидно, что самые верхние виды окна приложения больше не видны пользователю. Однако, с точки зрения окна вашего приложения, они по-прежнему являются самыми верхними представлениями, и поэтому они не исчезли из окна. Скорее эти представления исчезли, потому что исчезло окно приложения. Они не исчезли, потому что исчезли из окна.
Поэтому, когда пользователь переключается обратно на ваше приложение, они, очевидно, появляются на экране, потому что окно появляется снова. Но с точки зрения окна они совсем не исчезли. Поэтому контроллеры представления никогда не получают
viewWillAppear:animated
сообщение.источник
Свифт 4.2 / 5
источник
Просто попытайтесь сделать это как можно проще, см. Код ниже:
источник