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

时间:2013-04-07 15:52:36

标签: ios objective-c iphone xcode swift

我有一个View Controller,其值为0(标签),当我从另一个ViewController打开View Controller时,我已将viewDidAppear设置为标签上的值20。它工作正常,但当我关闭我的应用程序而不是我再次打开我的应用程序但值不会更改,因为viewDidLoadviewDidAppearviewWillAppear没有被调用。打开我的应用程序时如何打电话。我是否必须从applicationDidBecomeActive做任何事情?

8 个答案:

答案 0 :(得分:296)

对事件的确切顺序感到好奇,我按如下方式对应用程序进行了检测:(@ 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

答案 1 :(得分:126)

使用Objective-C

您应该在UIApplicationWillEnterForegroundNotification的{​​{1}}方法中注册ViewController,当应用从后台返回时,您可以在注册通知的方法中执行任何操作。当应用从后台返回到前台时,将不会调用viewDidLoad viewWillAppear viewDidAppear

ViewController

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

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

使用Swift

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

viewController

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

 override func viewDidLoad() {
    super.viewDidLoad()

     NSNotificationCenter.defaultCenter().addObserver(self, selector:"doYourStuff", name:
     UIApplicationWillEnterForegroundNotification, object: nil)
 }

 func doYourStuff(){
     // your code
 }

答案 2 :(得分:39)

Swift 3.0 ++版本

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

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

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

func doSomething(){
    //...
}

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

deinit {
    NotificationCenter.default.removeObserver(self)
}

答案 3 :(得分:4)

我认为注册UIApplicationWillEnterForegroundNotification是有风险的,因为您最终可能会有多个控制器对该通知作出反应。收到通知后,这些控制器仍然无法显示任何警告。

以下是我的操作:我直接从App的委托didBecomeActive方法强制调用活动控制器上的viewDidAppear:

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

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

迅速4.2。版本

MultiDataTrigger中向NotificationCenter注册,以在应用程序从后台返回时得到通知

MultiTrigger

实施应调用的方法。

viewDidLoad

NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil) 被破坏后,您可以删除观察者。仅在iOS9和macOS 10.11以下才需要

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

答案 6 :(得分:2)

尝试在AppDelegate applicationWillEnterForeground中添加它。

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

答案 7 :(得分:1)

根据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通知。 当我评论这些行时,它工作正常