13
votes

When my app enters the background, my modally presented view controller dismisses an alert view like so...

// called when view controller receives a UIApplicationDidEnterBackgroundNotification
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
    if (self.alertView) {
        [self.alertView dismissWithClickedButtonIndex:0 animated:NO];
        self.alertView = nil;
    }
}

When my app returns to the foreground without having been terminated, the alert view is gone. However, the bar button items in the navigation bar (from a UINavigationController) are still dimmed as if the alert view were still displayed.

Moreover, dismissing the modal view controller (by tapping a dimmed bar button item) reveals that the bar button items for the presenting view controller are also dimmed. The bar buttons items are functional, but they remain dimmed.

So how do I un-dim the bar button items? Or, how do I properly dismiss an alert view programmatically in iOS 7 in response to the app entering the background?

The iOS 7 UI Transition Guide states the following:

When an alert or action sheet appears, iOS 7 automatically dims the tint color of the views behind it. To respond to this color change, a custom view subclass that uses tintColor in its rendering should override tintColorDidChange to refresh the rendering when appropriate.

My navigation bars and bar button items are not custom views; I did not subclass them. I created the navigation bars in storyboard with their default attributes (same with the bar button items). So there's no place for me to override tintColorDidChange.

All of my views use the default value for their tintColor property.

I have tried re-seting the tint color to the default value without success:

if (self.alertView) {
        [self.alertView dismissWithClickedButtonIndex:0 animated:NO];
        self.view.tintColor = nil;
        self.view.window.tintColor = nil;
        self.alertView = nil;
    }

I have also tried re-seting the tint color in the view controller's viewDidAppear: without success.

I also tried setting the main view's tintAdjustmentMode to "normal" without success:

if (self.alertView) {
    [self.alertView dismissWithClickedButtonIndex:0 animated:NO];
    self.alertView = nil;

    self.view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
}

By the way, if the the app was terminated while in the background, the app relaunches with the bar button items having the correct tint (i.e., un-dimmed).

3
My alert views have been coming through the transition from background, much to my dismay. I will look at this more, too.HalR
Using [[UIApplication sharedApplication] keyWindow], check what the currently active window is. Since UIAlertView has its own window, it may be that that window does not get dismissed properly, leaving your bar (button items) dimmed. You can also try dismissing it before the app becomes active again (application:willEnterForeground:).Scott Berrevoets

3 Answers

9
votes

I'm pretty sure this is a bug on Apple's end. I've filed a bug report at https://bugreport.apple.com, please file a duplicate bug report to get Apple to pay attention to it, as that is how Apple assigns priority to bugs.

7
votes

I experienced the same bug in my app and successfully found a workaround. All you need to do is set tintAdjustmentMode to UIViewTintAdjustmentModeNormal on your application's main window after the UIAlertView is dismissed in background. Easy :)

5
votes

Although I can dismiss an alert view programmatically in response to a UIApplicationDidEnterBackgroundNotification, the automatic tint-dimming in iOS 7 will not get updated.

However, the automatic tint-dimming behavior will respond if I dismiss the alert view in response to a UIApplicationWillResignActiveNotification instead.

// called when view controller receives a UIApplicationWillResignActiveNotification
- (void)applicationWillResignActiveNotification:(NSNotification *)notification
{
    if (self.alertView) {
        [self.alertView dismissWithClickedButtonIndex:0 animated:NO];
        self.alertView = nil;
    }
}