当applicationWillEnterForeground被触发时更改UIView

7

我正在寻找一种方法,在将应用程序发送到后台时获取当前显示给用户的视图。

情况是,我在设置束中提供了外观选项,我希望在applicationWillEnterForeground被触发时生效。

有人对如何解决这个问题有建议吗?

我尝试注册一个NSNotification,但它太晚了,当NSNotification方法运行之前,视图已经出现给用户了。


@Sam,是的,我尝试了这两种方法。视图仍然被加载,所以在这些调用触发所需的更改之前,UIView已经显示出来了。 - bdparrish
你考虑过在 applicationDidEnterBackground期间更改视图吗?这样,您就无需担心在 applicationWillEnterForeground 显示它。这对我来说似乎有效。你具体在做什么?更改图片、添加子视图、应用转换?我想尝试复制您看到的错误行为。 - Sam
@Sam,问题在于他们可以退出应用程序更改应用程序设置,然后重新进入应用程序。我希望如果他们在重新进入应用程序时更改了这些设置,那么这些设置将立即生效。 - bdparrish
啊,我感觉很蠢,应该意识到了。你的问题提到了设置包和你想要的东西。我会在一个示例项目中尝试类似的东西。另外,如果你决定想在你的应用程序中添加设置,请查看In App Settings Kit - Sam
我刚刚向苹果提交了这个错误报告:应用程序从后台返回时无法更新UI。你有找到任何解决方法吗? - Sam
显示剩余2条评论
4个回答

7

要在用户将您的应用程序置于后台时获取当前显示的视图,请使用您的AppDelegate的applicationDidEnterBackground方法。

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Get current view...  
    // (get from UITabbarController or whatever logic you like)

    // For this code sample, just grab first UIView under the main window
    UIView *myView = [self.window.subviews objectAtIndex:0];
}

要在视图显示前更改视图,请使用AppDelegate的applicationWillEnterForeground方法,如下所示:

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 80, 80)];
    label.backgroundColor = [UIColor whiteColor];
    label.text = @"yo";

    [self.myLastView addSubview:label];
}

我知道你在问题中提到了applicationWillEnterForeground。你能否更具体地说明你想做什么或者可能包含代码?我实际上尝试过上面的代码并且视图更新了(我看到标签“yo”在我的视图上方)。
我最后的建议是尝试调用[view setNeedsDisplay][view setNeedsLayout],这应该强制UIView重新绘制自己。(注意-问题不是uiview更改不显示,而是它们在旧视图显示后才显示出来。似乎在挂起应用程序之前会拍摄屏幕截图,并且在恢复应用程序时最初显示此屏幕截图以提高性能)

上面的代码是用户所看到的很好的例子。标签"yo"出现在视图恢复后。我会尝试修复这个问题并重新发布。

编辑2

据我所知,恢复暂停的应用程序会显示应用程序最后已知状态的截图。我已经尝试查找相关文档,但没有找到。

备选方案1

当用户按下主页按钮时退出您的应用程序。

如果您在applicationWillResignActive:applicationWillTerminate:中保存应用程序的状态,则可以简单地恢复该状态(导航到用户上次停留的正确选项卡),并在用户查看之前在appDidFinishLaunchingWithOptions:中更新UI。要使您的应用程序在后台(暂停)时退出,请将键"Application does not run in background" - raw key: UIApplicationExitsOnSuspend设置为YES

这样做将确保用户在不看到以前的外观的情况下看到他们在设置中配置的应用程序。很抱歉我找不到更好的方法来解决这个问题。 :(

备选方案2

在您的应用程序内显示设置。

这显然需要进行设计更改,但越来越多的应用程序在应用内显示设置。一个流行的第三方库是In App Settings Kit。这使您可以通过包/ plist文件配置设置,就像您为全局应用程序设置一样。它看起来和行为也像全局设置。这将为您提供任何您想要的应用程序内完全控制。

我意识到这可能并不能完全回答你的问题,但我认为这应该有助于更好地展开讨论。你还需要什么具体帮助?目前有哪些问题或者不起作用的地方?我不知道你是否尝试过像我上面提供的简单代码示例,我曾经看到它能够正常工作,而你现在可能正在尝试更复杂的东西,由于某种原因它无法正常工作。如果我有足够的细节来查看,我很乐意帮助你解决问题。 - Sam
1
所以更详细地说,根控制器是一个UITabViewController,然后每个选项卡都是一个NavController或UIView。我想要能够捕获当前选中选项卡中的当前UIView。如果选择另一个选项卡然后再返回原始选项卡,设置将会改变。我还没有尝试过你的示例,但也许你的答案会随着新信息的出现而改变。 - bdparrish
请告诉我,如果任何一种替代方案适用于您。不幸的是,当恢复应用程序时,在显示视图之前似乎没有更新视图的方法。 - Sam
1
如果不希望终止应用程序,是否可以在 applicationWillResignActive: 中显示一个空白屏幕,以便操作系统将其作为“最后状态”截图?当您重新进入应用程序时,可能会看起来有点突兀,但可能比由于首选项更改而导致布局突然切换要少得多。 - jrturton
@jrturton 是的,你可以这样做。我尝试在applicationDidEnterBackground:中进行UI更改,当应用程序恢复时,我立即看到了它。所以,是的,这肯定可行。 - Sam
看起来有人在问题Alter view before applicationWillEnterForeground中提供了类似的解决方案。 - Sam

0

以防有人遇到相同的问题:
看来苹果在 iOS7 上实现了一个新属性 UIApplication,当重新进入前台时防止使用先前拍摄的快照 - ignoreSnapshotOnNextApplicationLaunch


0

我猜你可能搞反了。

系统可能会对当前屏幕进行快照,并在你的应用程序恢复到前台时显示该快照。也许这个快照显示的是旧的外观,在你有机会在applicationWillEnterForeground:时间更改它之前。

所以,当你得到applicationWillEnterForeground:时进行更改,那么快照将从你想要恢复的地方进行拍摄。


0
在每个viewDidLoad中,您总是可以发布一个通知,参见NSNotification Class Reference,您可以将视图的引用存储在NSUserDefaults中,然后在用户返回时执行所需操作applicationWillEnterForeground:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接