ios 从后台打开应用程序时不会调用 ViewDidAppear

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15864364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:04:52  来源:igfitidea点击:

ViewDidAppear is not called when opening app from background

iosobjective-ciphonexcodeswift

提问by Zohaib

I have a View Controller in which my value is 0 (label) and when I open that View Controller from another ViewControllerI have set viewDidAppearto set value 20 on label. It works fine but when I close my app and than again I open my app but the value doesn't change because viewDidLoad, viewDidAppearand viewWillAppearnothing get called. How can I call when I open my app. Do I have to do anything from applicationDidBecomeActive?

我有一个视图控制器,其中我的值为 0(标签),当我从另一个视图控制器打开该视图控制器时,ViewController我已将viewDidAppear标签上的值设置为 20。它工作正常,但是当我关闭我的应用程序并再次打开我的应用程序时,但该值不会更改,因为viewDidLoadviewDidAppear并且viewWillAppear没有调用任何内容。当我打开我的应用程序时如何调用。我必须做些什么applicationDidBecomeActive吗?

回答by danh

Curious about the exact sequence of events, I instrumented an app as follows: (@Zohaib, you can use the NSNotificationCenter code below to answer your question).

出于对事件的确切顺序感到好奇,我按如下方式检测了一个应用程序:(@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");
}

At launch, the output looks like this:

启动时,输出如下所示:

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

Enter the background then reenter the foreground:

进入背景然后重新进入前景:

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

回答by nsgulliver

Using Objective-C

使用 Objective-C

You should register a UIApplicationWillEnterForegroundNotificationin your ViewController's viewDidLoadmethod and whenever app comes back from background you can do whatever you want to do in the method registered for notification. ViewController's viewWillAppearor viewDidAppearwon't be called when app comes back from background to foreground.

你应该UIApplicationWillEnterForegroundNotification在你ViewControllerviewDidLoad方法中注册 a ,每当应用程序从后台返回时,你可以在注册通知的方法中做任何你想做的事情。ViewControllerviewWillAppear中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.
}

Don't forget to unregister the notification you are registered for.

不要忘记取消注册您注册的通知。

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Noteif you register your viewControllerfor UIApplicationDidBecomeActiveNotificationthen your method would be called every time your app becomes active, It is not recommended to register viewControllerfor this notification .

请注意,如果您注册了viewControllerforUIApplicationDidBecomeActiveNotification那么您的方法将在每次您的应用程序变为活动状态时被调用,不建议注册viewController此通知。

Using Swift

使用 Swift

For adding observer you can use the following code

要添加观察者,您可以使用以下代码

 override func viewDidLoad() {
    super.viewDidLoad()

     NotificationCenter.default.addObserver(self, selector: "doYourStuff", name: UIApplication.willEnterForegroundNotification, object: nil)
 }

 func doYourStuff(){
     // your code
 }

To remove observer you can use deinit function of swift.

要删除观察者,您可以使用 swift 的 deinit 函数。

deinit {
    NotificationCenter.default.removeObserver(self)
}

回答by Fangming

Swift 3.0 ++ version

斯威夫特 3.0++ 版本

In your viewDidLoad, register at notification center to listen to this opened from background action

在您的viewDidLoad,在通知中心注册以收听此从后台打开的操作

NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)

Then add this function and perform needed action

然后添加此功能并执行所需的操作

func doSomething(){
    //...
}

Finally add this function to clean up the notification observer when your view controller is destroyed.

最后添加此函数以在您的视图控制器被销毁时清理通知观察者。

deinit {
    NotificationCenter.default.removeObserver(self)
}

回答by gebirgsb?rbel

Swift 4.2. version

斯威夫特 4.2。版本

Register with the NotificationCenter in viewDidLoadto be notified when the app returns from background

向 NotificationCenter 注册以在viewDidLoad应用程序从后台返回时收到通知

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)

Implement the method that should be called.

实现应该调用的方法。

@objc private func doSomething() {
    // Do whatever you want, for example update your view.
}

You can remove the observer once the ViewControlleris destroyed. This is only required below iOS9 and macOS 10.11

一旦观察者ViewController被销毁,您就可以移除观察者。仅在 iOS9 和 macOS 10.11 以下才需要

deinit {
    NotificationCenter.default.removeObserver(self)
}

回答by andreagiavatto

Just have your view controller register for the UIApplicationWillEnterForegroundNotificationnotification and react accordingly.

只需让您的视图控制器注册UIApplicationWillEnterForegroundNotification通知并做出相应的反应。

回答by Erwan

I think registering for the UIApplicationWillEnterForegroundNotification is risky as you may end up with more than one controller reacting to that notification. Nothing garanties that these controllers are still visible when the notification is received.

我认为注册 UIApplicationWillEnterForegroundNotification 是有风险的,因为您最终可能会有多个控制器对该通知做出反应。当收到通知时,不能保证这些控制器仍然可见。

Here is what I do: I force call viewDidAppear on the active controller directly from the App's delegate didBecomeActive method:

这是我所做的:我直接从应用程序的委托 didBecomeActive 方法强制调用活动控制器上的 viewDidAppear :

Add the code below to - (void)applicationDidBecomeActive:(UIApplication *)application

将下面的代码添加到 - (void)applicationDidBecomeActive:(UIApplication *)application

UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
    activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];

回答by richc

try adding this in AppDelegate applicationWillEnterForeground.

尝试在 AppDelegate applicationWillEnterForeground 中添加它。

func applicationWillEnterForeground(_ application: UIApplication) {        
    // makes viewWillAppear run
    self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
    self.window?.rootViewController?.endAppearanceTransition()
}

回答by Lakshmi

As per Apple's documentation:

根据 Apple 的文档:

(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;

Description:
Tells a child controller its appearance is about to change. If you are implementing a custom container controller, use this method to tell the child that its views are about to appear or disappear. Do not invoke viewWillAppear:, viewWillDisappear:, viewDidAppear:, or viewDidDisappear:directly.

描述:
告诉子控制器它的外观即将改变。如果您正在实现自定义容器控制器,请使用此方法告诉孩子它的视图即将出现或消失不要直接调用viewWillAppear:, viewWillDisappear:, viewDidAppear:, 或viewDidDisappear:

(void)endAppearanceTransition;

Description:

描述:

Tells a child controller its appearance has changed. If you are implementing a custom container controller, use this method to tell the child that the view transition is complete.

告诉子控制器它的外观已经改变。如果您正在实现自定义容器控制器,请使用此方法告诉孩子视图转换已完成。

Sample code:

示例代码:

(void)applicationDidEnterBackground:(UIApplication *)application
{

    [self.window.rootViewController beginAppearanceTransition: NO animated: NO];  // I commented this line

    [self.window.rootViewController endAppearanceTransition]; // I commented this line

}

Question: How I fixed?

问题:我是如何修复的?

Ans: I found this piece of lines in application. This lines made my app not recieving any ViewWillAppear notification's. When I commented these lines it's working fine.

Ans: 我在应用程序中发现了这条线。这行使我的应用程序没有收到任何 ViewWillAppear 通知。当我评论这些行时,它工作正常