Dismissing UIAlertViews when entering background s

2019-01-10 03:38发布

Apple recommends dismissing any UIAlertViews/UIActionSheets when entering background state in iOS 4. This is to avoid any confusion on the user's part when he relaunches the application later. I wonder how I could elegantly dismiss all UIAlertViews at once, without retaining a reference to it everytime I set one up...

Any idea ?

12条回答
趁早两清
2楼-- · 2019-01-10 04:07

The straightforward way is to hold a reference to the UIAlertView so you can dismiss it. Of course as petert mentioned you can do it with a Notification or use the delegate method on UIApplication

applicationWillResignActive:

does not always mean that you are going to the background. You will for example also receive that delegate call and notification (you get both) when the user gets a phone call or receives and SMS. So you have to decide what should happen if the user gets an SMS and presses cancel to stay in your app. You maybe want to make sure that your UIAlertView is still there.

So I would dismiss the UIAlertView and save the state in the delegate call when you really go into the background:

applicationDidEnterBackground:

Have a look at Session 105 - Adopting Multitasking on iOS4 of WWDC10 available for free at developer.apple.com. It gets interesting at 16:00 min

Check out this graphic to understand the different states of an application

查看更多
该账号已被封号
3楼-- · 2019-01-10 04:07

Create category on UIAlert View

Use http://nshipster.com/method-swizzling/ Swizzle "show" method

Keep track of alert view shown by keeping week references in array.

- When you want to remove all data call Dismiss on saved alert views and empty an array.

查看更多
做自己的国王
4楼-- · 2019-01-10 04:09

A totally different approach is a recursive search.

Recursive function for your application delegate

- (void)checkViews:(NSArray *)subviews {
    Class AVClass = [UIAlertView class];
    Class ASClass = [UIActionSheet class];
    for (UIView * subview in subviews){
        if ([subview isKindOfClass:AVClass]){
            [(UIAlertView *)subview dismissWithClickedButtonIndex:[(UIAlertView *)subview cancelButtonIndex] animated:NO];
        } else if ([subview isKindOfClass:ASClass]){
            [(UIActionSheet *)subview dismissWithClickedButtonIndex:[(UIActionSheet *)subview cancelButtonIndex] animated:NO];
        } else {
            [self checkViews:subview.subviews];
        }
    }
}

Calling it from the applicationDidEnterBackground procedure

[self checkViews:application.windows];
查看更多
姐就是有狂的资本
5楼-- · 2019-01-10 04:13

My call would be to add a category to UIAlertview adding the following function :

- (void) hide {
  [self dismissWithClickedButtonIndex:0 animated:YES];
}

And to suscribe to UIApplicationWillResignActiveNotification :

[[NSNotificationCenter defaultCenter] addObserver:alertView selector:@selector(hide) name:@"UIApplicationWillResignActiveNotification" object:nil];
查看更多
姐就是有狂的资本
6楼-- · 2019-01-10 04:15

As someone mentioned in a comment: the accepted answer isn't the best/cleanest one since iOS 4.0 when we have blocks! Here's how I do it:

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Alert!" message:@"This alert will dismiss when application resigns active!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification){
        [alert dismissWithClickedButtonIndex:0 animated:NO];
    }];
查看更多
趁早两清
7楼-- · 2019-01-10 04:16

if you only have one or two specific alert windows you show (as do most apps), then you can just create an assign ivar to the alert:

@property (nonatomic, assign) UIAlertView* alertview;

Then, in the app delegate:

[self.viewController.alertview dismissWithClickedButtonIndex:[self.viewController.alertview cancelButtonIndex] animated:NO];

You can put this in applicationDidEnterBackground: or wherever you see fit. It closes the alert programmatically upon application exit. I've been doing this and it works great.

查看更多
登录 后发表回答