2013-02-26 47 views
1

应用程序返回的我的导航控制器的景色之一,我有一个方法- (void) loadAlert是得到一个网页的内容,分析它,并把上的相关内容UITextView。该方法调用位于我的视图控制器的viewDidAppear:部分。当视图第一次加载时,以及视图在导航到时全部显示时,它工作正常。当调用一个方法来重新加载视图从背景

我也希望这个数据加载发生在应用程序从后台返回。由于许多职位#1和其他来源的指示,我把我的方法调用中applicationDidBecomeActive::当从后台应用程序返回

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    MainViewController *mainView = [[mainViewController alloc] init]; 
    [mainView loadAlert]; 
} 

然而,没有在视图中出现。我期望UITextView清除,UIActivityIndicatorView旋转,而内容是从互联网获得的,而新的内容将被加载到UITextView

我知道该方法正在被调用,但在视图内没有任何事情发生。我的感觉是,这个方法被调用时视图还没有加载。 我在哪里可以放置我的方法调用,以便应用程序从后台返回时,如果此特定视图是导航控制器中显示的当前视图,它实际上会刷新UI?

+0

这是错误的方法。当从后台返回时,你需要'applicationWillEnterForeground:',而不是'applicationDidBecomeActive:'。 – rmaddy 2013-02-26 22:10:42

回答

5

可以使用UIApplicationWillEnterForegroundNotificationUIApplicationDidBecomeActiveNotification,这是很有效的倾听这些通知在应用程序中的任何地方,你需要将控制器注册到其中的一个通知,并使用你的方法来显示你想要的任何东西。

 [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(showYourView) 
               name:UIApplicationWillEnterForegroundNotification object:nil]; 

-(void) showYouView(){ 
// do your stuff 
} 

注意

最好的办法是使用UIApplicationWillEnterForegroundNotification,因为当用户来自后台前台它将只运行,而另一方面UIApplicationDidBecomeActiveNotification运行,每一次你的应用程序变得活跃

+1

简单而有效。谢谢 – DGund 2013-02-26 22:23:43

+0

除了这是错误的通知。 “UIApplicationDidBecomeActiveNotification”被称为远多于从后台返回。不要忘记删除观察者,否则你的应用会在某个时候崩溃。 – rmaddy 2013-02-26 22:25:56

+0

@rmaddy我没有使用'applicationWillEnterForeground'。我应该何时去除观察者? – DGund 2013-02-26 22:29:21

2

您正在创建的mainViewController一个新实例,而不是使用相同的实例,它已经存在。每当你做一个mainViewController *mainView = [[mainViewController alloc] init];,这是一个新的实例。您应该尝试访问viewcontrollers堆栈中的同一个实例,并根据该实例调用此方法。

我在哪里可以把我的方法调用,这样,当从 后台应用程序的回报,如果这个特定视图中显示 导航控制器,目前看来,它实际上将刷新UI?

假设你有你的UINavigationController添加为您的appdelegate的属性,你可以使用下面的代码在applicationWillEnterForeground调用loadAlert在topViewController。

UIViewController *aViewController = self.navigationController.topViewController; 
if ([aViewController isKindOfClass:[mainViewController class]]) { 
    [(mainViewController *)aViewController loadAlert]; 
} 

请注意,请用大写字母开头。例如: - 您应该使用MainViewController而不是mainViewController,通常表示一个变量名称。

更新:

如果您使用的是UIApplicationWillEnterForegroundNotification方法,你应该在notificationMethod方法中添加上面的代码,以确保mainViewController是当前视图控制器,它是可见的。否则它会显示一些意想不到的行为。

所以这样的事情应该是不错的:

- (void)notificationMethod { 

    UIViewController *aViewController = self.navigationController.topViewController; 
    if ([aViewController isKindOfClass:[mainViewController class]]) { 
     [(mainViewController *)aViewController loadAlert]; 
    } 
} 
+1

谢谢你,我测试了这个,它的工作原理 – DGund 2013-02-26 22:24:55

+0

@DGund,很高兴知道这一点。请使用'UIViewController * aViewController = self.navigationController.topViewController; if([aViewController isKindOfClass:[mainViewController class]]){(mainViewController *)aViewController loadAlert]; }'如果你想确保当'mainViewController'不可见时你没有调用loadAlert。使用通知方法,您无法确定屏幕上当前显示哪一个,如果您不希望屏幕在不可见时刷新,可能会导致意外行为。 – iDev 2013-02-26 22:26:40

+1

这不是一个相当复杂的方法来解决这个问题吗?让实际的视图控制器监听正确的通知并采取相应的行动是否更简洁?将这个逻辑放在应用程序委托中确实会破坏封装。 – rmaddy 2013-02-26 22:30:18

0

我的需求与我的项目完全相同,我不得不通过通知中心系统来处理此问题。

首先,你需要在你的应用程序进入前景启动通知:

- (void)applicationWillEnterForeground:(UIApplication *)application 
{ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"app_entering_foreground" object:self]; 
} 

然后,你需要真正听在你需要它这个特别的通知。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateUI) @"app_entering_foreground" object:nil]; 
+0

已经有系统为此提供了通知:'UIApplicationWillEnterForegroundNotification'。没有必要实现'applicationWillEnterForeground:',以便您可以发布自定义通知。 – rmaddy 2013-02-26 22:12:23

+0

好吧,不知道。为了解释如何抛出自定义通知,我会让我的答案。 – Kirualex 2013-02-26 22:23:53

2

处理正确的方法是让你的UIApplicationWillEnterForegroundNotificationMainViewController寄存器。然后,当收到通知时,您可以拨打loadAlert方法。

在MainViewController.m:

- (void)enterForeground { 
    [self loadAlert]; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; 
} 

- (void)dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; 
} 

你并不需要做应用程序的委托对这样的东西。这样,MainViewController负责知道应该发生什么以及何时发生。

+0

您提到移除观察者。我看到你在'dealloc'中做了这个,但我的应用使用ARC。我还需要吗? – DGund 2013-02-26 22:31:19

+0

@DGund,会的dealloc即使在ARC项目被调用。只是你不需要在那里做发布声明。 – iDev 2013-02-26 22:33:19

+0

是,'dealloc'是正确的地方,即使ARC。我在我的答案中假定了ARC。注意没有调用'[super dealloc]'。 – rmaddy 2013-02-26 22:33:41

相关问题