179

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

4

8 回答 8

316

对事件的确切顺序感到好奇,我按如下方式检测了一个应用程序:(@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
于 2013-04-07T16:32:49.537 回答
136

使用 Objective-C

UIApplicationWillEnterForegroundNotification您应该在您ViewController的方法中注册 a ,viewDidLoad并且每当应用程序从后台返回时,您都可以在注册通知的方法中执行您想做的任何事情。ViewControllerviewWillAppearviewDidAppear当应用程序从后台返回到前台时不会被调用。

-(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此通知。

使用斯威夫特

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

 override func viewDidLoad() {
    super.viewDidLoad()

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

 func doYourStuff(){
     // your code
 }

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

deinit {
    NotificationCenter.default.removeObserver(self)
}
于 2013-04-07T16:28:45.583 回答
43

斯威夫特 3.0++ 版本

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

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

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

func doSomething(){
    //...
}

最后添加这个函数来在你的视图控制器被销毁时清理通知观察者。

deinit {
    NotificationCenter.default.removeObserver(self)
}
于 2017-07-12T19:54:14.823 回答
17

斯威夫特 4.2。版本

注册 NotificationCenterviewDidLoad以在应用从后台返回时收到通知

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)
}
于 2018-11-26T14:36:54.620 回答
3

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

于 2013-04-07T16:05:12.320 回答
3

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

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

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

UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
    activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];
于 2014-10-31T09:20:03.073 回答
3

尝试在 AppDelegate applicationWillEnterForeground 中添加它。

func applicationWillEnterForeground(_ application: UIApplication) {        
    // makes viewWillAppear run
    self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
    self.window?.rootViewController?.endAppearanceTransition()
}
于 2017-03-03T18:16:16.180 回答
2

根据 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

}

问题:我是如何解决的?

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

于 2017-06-28T21:06:17.640 回答