Changing UIView when applicationWillEnterForegroun

2020-03-18 05:37发布

问题:

I am looking for a way to grab the current view being shown to the user when they send the application to the background.

The situation is that I have provided options in my settings bundle for look and feel that I would like to take effect when the applicationWillEnterForeground is fired.

Anyone have a suggestion as to how to attack this problem?

I tried to register a NSNotification, but it fires to late and the view appears to the user before the NSNotification method runs.

回答1:

To grab the current view being shown when the user backgrounds your app, use your AppDelegate's applicationDidEnterBackground method.

- (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];
}

To change the view before it shows, use the AppDelegate's applicationWillEnterForeground method like this:

- (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];
}

I realize you mentioned the applicationWillEnterForeground in your question. Can you be more specific with what you are trying to do or possibly include code? I actually tried the code above and the view update (I see the label "yo" above my view).

My last suggestion is to try calling [view setNeedsDisplay] and [view setNeedsLayout] which should force the UIView to redraw itself. (note - issue isn't that uiview changes don't show up, issue is that they show up after the old view is shown. It appears a screenshot is taken before suspending app and this screenshot is initially shown upon resuming app for performance)

Edit

Code above is a good example of what user is seeing. The label "yo" shows up, but only after the view is restored. I'll see if I can fix this and repost.

Edit 2

It appears that resuming a suspended app shows a captured screenshot of the app's last known state as far as I can tell. I've tried to find docs to this effect, but I can't find it.

Alternative Solution 1

Have your app exit when the user hits the home button.

If you save the state of your app in either applicationWillResignActive: or applicationWillTerminate:, you can simply restore that state (navigate to correct tab user was last on) and in appDidFinishLaunchingWithOptions: you can update the UI before the user sees it. To have your app exit when backgrounded (suspended) put the key "Application does not run in background" - raw key: UIApplicationExitsOnSuspend to YES.

Doing this will guarantee that the user will see your app the way they configured it in settings without seeing a flicker of what it used to look like. I'm sorry I couldn't find a better way to do this. :(

Alternative Solution 2

Display your settings inside your app.

This obviously would require a design change, however more and more apps are showing settings inside the app. A popular third party library is In App Settings Kit. This lets you configure settings via a bundle / plist file just like you would for global app settings. It also looks and behaves just like the global settings. This will give you FULL control of any behavior you want inside your app.



回答2:

I'm going to guess that you have it backwards.

The system may take a snapshot of the current screen, and it shows this when your app is restored to the foreground. It may be that this snapshot is showing the old look, before you get a chance to change it at applicationWillEnterForeground: time.

So, change when you get applicationWillEnterForeground:, then the snapshot will be taken from what you want to restore to.



回答3:

In each viewDidLoad you can always post a notification, see NSNotification Class Reference, you can either store a reference to the view in NSUserDefaults, then do what you need to do when the user returns in applicationWillEnterForeground:



回答4:

Just in case someone comes around with the same problem:
It seems that Apple has implemented a new property in iOS7 on UIApplication which prevents using the previously taken snapshot when reentering into foreground - ignoreSnapshotOnNextApplicationLaunch



标签: ios uiview