ViewDidAppear не вызывается при открытии приложения из фона
У меня есть View Controller, в котором мое значение равно 0 (метка), и когда я открываю этот View Controller из другого ViewController
Я поставил viewDidAppear
установить значение 20 на этикетке. Это работает нормально, но когда я закрываю свое приложение и затем снова я открываю свое приложение, но значение не меняется, потому что viewDidLoad
, viewDidAppear
а также viewWillAppear
ничего не вызывать. Как я могу позвонить, когда я открою свое приложение. Должен ли я сделать что-нибудь из applicationDidBecomeActive
?
8 ответов
Заинтересовавшись точной последовательностью событий, я оснастил приложение следующим образом: (@Zohaib, вы можете использовать приведенный ниже код NSNotificationCenter, чтобы ответить на ваш вопрос).
// AppDelegate.m
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"app will enter foreground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(@"app did become active");
}
// ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"view did load");
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)appDidBecomeActive:(NSNotification *)notification {
NSLog(@"did become active notification");
}
- (void)appWillEnterForeground:(NSNotification *)notification {
NSLog(@"will enter foreground notification");
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"view will appear");
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"view did appear");
}
При запуске вывод выглядит так:
2013-04-07 09:31:06.505 myapp[15459:11303] view did load
2013-04-07 09:31:06.507 myapp[15459:11303] view will appear
2013-04-07 09:31:06.511 myapp[15459:11303] app did become active
2013-04-07 09:31:06.512 myapp[15459:11303] did become active notification
2013-04-07 09:31:06.517 myapp[15459:11303] view did appear
Введите фон, затем снова введите передний план:
2013-04-07 09:32:05.923 myapp[15459:11303] app will enter foreground
2013-04-07 09:32:05.924 myapp[15459:11303] will enter foreground notification
2013-04-07 09:32:05.925 myapp[15459:11303] app did become active
2013-04-07 09:32:05.926 myapp[15459:11303] did become active notification
Использование Objective-C
Вы должны зарегистрировать UIApplicationWillEnterForegroundNotification
в вашем ViewController
"s viewDidLoad
метод и всякий раз, когда приложение возвращается из фона, вы можете делать все, что вы хотите сделать в методе, зарегистрированном для уведомления. ViewController
viewWillAppear или viewDidAppear не будут вызываться при возврате приложения из фона на передний план.
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doYourStuff)
name:UIApplicationWillEnterForegroundNotification object:nil];
}
-(void)doYourStuff{
// do whatever you want to do when app comes back from background.
}
Не забудьте отменить регистрацию уведомления, на которое вы зарегистрированы.
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Обратите внимание, если вы зарегистрируете свой viewController
за UIApplicationDidBecomeActiveNotification
тогда ваш метод будет вызываться каждый раз, когда ваше приложение станет активным, регистрация не рекомендуется viewController
для этого уведомления.
Использование Swift
Для добавления наблюдателя вы можете использовать следующий код
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
UIApplicationWillEnterForegroundNotification, object: nil)
}
func doYourStuff(){
// your code
}
Для удаления наблюдателя вы можете использовать функцию deinit swift.
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Версия Swift 3.0 ++
В вашем viewDidLoad
, зарегистрируйтесь в центре уведомлений, чтобы прослушать это открытое из фонового действия
NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
Затем добавьте эту функцию и выполните необходимые действия
func doSomething(){
//...
}
Наконец добавьте эту функцию, чтобы очистить наблюдателя уведомлений, когда ваш контроллер представления разрушен.
deinit {
NotificationCenter.default.removeObserver(self)
}
Свифт 4.2. версия
Зарегистрируйтесь в Центре уведомлений в viewDidLoad
получать уведомления, когда приложение возвращается из фона
NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)
Реализуйте метод, который должен быть вызван.
@objc private func doSomething() {
// Do whatever you want, for example update your view.
}
Вы можете удалить наблюдателя, как только ViewController
уничтожен Это требуется только ниже iOS9 и MacOS 10.11
deinit {
NotificationCenter.default.removeObserver(self)
}
Я думаю, что регистрация для UIApplicationWillEnterForegroundNotification опасна, так как вы можете получить более одного контроллера, реагирующего на это уведомление. Ничто не гарантирует, что эти контроллеры все еще видны при получении уведомления.
Вот что я делаю: я принудительно вызываю viewDidAppear на активном контроллере прямо из делегата приложения метода didBecomeActive:
Добавьте код ниже, чтобы - (void)applicationDidBecomeActive:(UIApplication *)application
UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];
Просто зарегистрируйте свой контроллер вида для UIApplicationWillEnterForegroundNotification
уведомление и реагировать соответственно.
Попробуйте добавить это в AppDelegate applicationWillEnterForeground.
func applicationWillEnterForeground(_ application: UIApplication) {
// makes viewWillAppear run
self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
self.window?.rootViewController?.endAppearanceTransition()
}
Согласно документации Apple:
(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;
Описание:
Сообщает дочернему контроллеру, что его внешний вид скоро изменится. Если вы реализуете пользовательский контроллер контейнера, используйте этот метод, чтобы сообщить дочернему элементу о том, что его представления должны появиться или исчезнуть. Не призывать viewWillAppear:
, viewWillDisappear:
, viewDidAppear:
, или же viewDidDisappear:
напрямую
(void)endAppearanceTransition;
Описание:
Сообщает дочернему контроллеру, что его внешний вид изменился. Если вы реализуете пользовательский контроллер контейнера, используйте этот метод, чтобы сообщить дочернему элементу, что переход представления завершен.
Образец кода:
(void)applicationDidEnterBackground:(UIApplication *)application
{
[self.window.rootViewController beginAppearanceTransition: NO animated: NO]; // I commented this line
[self.window.rootViewController endAppearanceTransition]; // I commented this line
}
Вопрос: как я исправил?
Ответ: Я нашел этот кусок строк в приложении. Эти строки заставили мое приложение не получать никаких уведомлений ViewWillAppear. Когда я прокомментировал эти строки, все работает нормально.