UIAlertView在IOS 9中首次被弃用

119

我已经尝试了几种方法来使用UIAlertController替代UIAlertView。我尝试了几种方式,但是无法让警告操作起作用。这是我的代码,在IOS 8和IOS 9中运行良好,但现在显示为弃用标志。我尝试了下面的优雅建议,但在这种情况下无法使其正常工作。我需要提交我的应用程序,这是要解决的最后一件事情。谢谢您提供进一步的建议。我是一个新手。

#pragma mark - BUTTONS ================================
- (IBAction)showModesAction:(id)sender {
NSLog(@"iapMade: %d", iapMade3);

// IAP MADE ! ===========================================
if (!iapMade3) {

    //start game here
    gamePlaysCount++;
    [[NSUserDefaults standardUserDefaults]setInteger:gamePlaysCount forKey:@"gamePlaysCount"];
    NSLog(@"playsCount: %ld", (long)gamePlaysCount);

    if (gamePlaysCount >= 4) {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Basic"
                                                     message: THREE_PLAYS_LIMIT_MESSAGE
                                                    delegate:self
                                           cancelButtonTitle:@"Yes, please"
                                           otherButtonTitles:@"No, thanks", nil];
       [alert show];

        NSString *path = [[NSBundle mainBundle] pathForResource:@"cow" ofType:@"wav"];
        _pop =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
        [_pop play];
        [self dismissViewControllerAnimated:true completion:nil];

    } else {
        if (gamePlaysCount == 1)  {
            // Create & store the next 5 mins when player gets 3 more lives
            nextDateToPlay = [[NSDate date] dateByAddingTimeInterval:60*60*0.1];
            NSLog(@"CURRENT DATE: %@", [NSDate date]);
            NSLog(@"NEXT DAY: %@", nextDateToPlay);
            [[NSUserDefaults standardUserDefaults]setObject: nextDateToPlay    forKey:@"nextDateToPlay"];
            NSLog(@"nextDateToPlay: %@", nextDateToPlay);

            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Basic"
                                                           message:  THREE_PLAYS_LIMIT_MESSAGE2
                                                          delegate:self
                                                 cancelButtonTitle:@"Got it!"
                                                 otherButtonTitles:@"Start", nil];
            [alert show];
        } else {

            if (gamePlaysCount == 3)  {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Basic"
                                                               message: THREE_PLAYS_LIMIT_MESSAGE3
                                                              delegate:self
                                                     cancelButtonTitle:@"Yep, I Know!"
                                                     otherButtonTitles:@"Start", nil];
                [alert show];
            }
        }
    }
}

}

// IAP NOT MADE =============================

#pragma mark - ALERTVIEW DELEGATE ============================

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:@"Yes, please"]) {

    UIStoryboard *storyboard = self.storyboard;
    MenuViewController *svc = [storyboard instantiateViewControllerWithIdentifier:@"Store"];
    svc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentViewController:svc animated:YES completion:nil];

        }

}

1
问题不清楚。你想要什么? - Moumou
UIAlertView在IOS 9中已被弃用,我们必须使用preferredStyle为UIAlertControllerStyleAlert的UIAlertController。然而,当我使用UIAlertController方法时,警告框不会显示。我尝试了下面的解决方案,但仍然无法显示警告视图。谢谢。 - Bux
好的。你可以展示一下你已经做了什么,还有哪些地方不起作用吗? - Moumou
1
在呈现完毕后,您需要调用 [self dismissViewControllerAnimated:true completion:nil]; 以关闭警告控制器。 - Adnan Aftab
3
这是一个重要的问题,因为UIAlertController相当新,许多开发人员会担心它被弃用。不合理的负评对一个有效的问题有不良影响。 那些在编辑后仍然给问题投了反对票的人应该改变他们的票。但是,“反对票巨魔”由于反对票而获得徽章,通常不会这样做。SO论坛的管理员应该有一种方法来解决这个问题。 - Totoro
显示剩余2条评论
10个回答

251

iOS8以后,苹果提供了新的UIAlertController类,您可以使用它来代替现在已经被弃用的UIAlertView。在弃用消息中也明确说明了这一点:

UIAlertView已过时。请改用UIAlertController,并设置preferredStyle为UIAlertControllerStyleAlert

所以,您应该像这样使用:

UIAlertController * alert = [UIAlertController
                alertControllerWithTitle:@"Title"
                                 message:@"Message"
                          preferredStyle:UIAlertControllerStyleAlert];



UIAlertAction* yesButton = [UIAlertAction
                    actionWithTitle:@"Yes, please"
                              style:UIAlertActionStyleDefault
                            handler:^(UIAlertAction * action) {
                                //Handle your yes please button action here
                            }];

UIAlertAction* noButton = [UIAlertAction
                        actionWithTitle:@"No, thanks"
                                  style:UIAlertActionStyleDefault
                                handler:^(UIAlertAction * action) {
                                   //Handle no, thanks button                
                                }];

[alert addAction:yesButton];
[alert addAction:noButton];

[self presentViewController:alert animated:YES completion:nil];

2
谢谢您的快速回复。我尝试了这个,但弹出窗口没有显示出来。当我添加“Yes please”操作时也是如此。 - Bux
1
你能给我展示一下你的代码吗?因为它对我来说运行得很好。请确保你在主线程上执行这段代码。 - Adnan Aftab
你能把你的代码放在问题里吗?这样每个人都可以看到。 - Adnan Aftab
嗨,我添加了适用于IOS8和IOS9的完整代码,但被标记为已弃用。我尝试了几种方法来实现你的代码,但是警报没有显示,并且打开商店视图控制器的操作也无法正常运行。谢谢你的帮助。 - Bux
如果您想在视图控制器之外使用新主题,请使用以下代码:UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(...) - Ali Beadle
显示剩余3条评论

24
//Calling     
[self showMessage:@"There is no internet connection for this device"
                    withTitle:@"Error"];

//Method

-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{

 UIAlertController * alert=   [UIAlertController
                                  alertControllerWithTitle:title
                                  message:message
                                  preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

        //do something when click button
    }];
    [alert addAction:okAction];
    UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
    [vc presentViewController:alert animated:YES completion:nil];
}

如果您想在NSObject类中使用此警报,应该像这样使用:

-(void)showMessage:(NSString*)message withTitle:(NSString *)title{
dispatch_async(dispatch_get_main_queue(), ^{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    }]];

    [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alertController animated:YES completion:^{
    }];
});
}

14

新实现的 Swift 版本为:

 let alert = UIAlertController(title: "Oops!", message:"your message", preferredStyle: .Alert)
 alert.addAction(UIAlertAction(title: "Okay.", style: .Default) { _ in })
 self.presentViewController(alert, animated: true){}

11

Xcode 8 + Swift

假设self是一个UIViewController

func displayAlert() {
    let alert = UIAlertController(title: "Test",
                                  message: "I am a modal alert",
                                  preferredStyle: .alert)
    let defaultButton = UIAlertAction(title: "OK",
                                      style: .default) {(_) in
        // your defaultButton action goes here
    }
    
    alert.addAction(defaultButton)
    present(alert, animated: true) { 
        // completion goes here
    }
}

如果self是视图,我们该如何实现这一点? - Subin K Kuriakose
一个视图没有做业务逻辑的必要。重新思考你的架构,让控制器呈现视图(MVVM或MVC)。 - SwiftArchitect

7
使UIAlertController+AlertController类别为:
UIAlertController+AlertController.h
typedef void (^UIAlertCompletionBlock) (UIAlertController *alertViewController, NSInteger buttonIndex);

@interface UIAlertController (AlertController)

+ (instancetype)showAlertIn:(UIViewController *)controller
                  WithTitle:(NSString *)title
                    message:(NSString *)message
          cancelButtonTitle:(NSString *)cancelButtonTitle
          otherButtonTitles:(NSString *)otherButtonTitle
                   tapBlock:(UIAlertCompletionBlock)tapBlock;
@end

UIAlertController+AlertController.m

@implementation UIAlertController (NTAlertController)

+ (instancetype)showAlertIn:(UIViewController *)controller
                  WithTitle:(NSString *)title
                    message:(NSString *)message
          cancelButtonTitle:(NSString *)cancelButtonTitle
          otherButtonTitles:(NSString *)otherButtonTitle
                   tapBlock:(UIAlertCompletionBlock)tapBlock {

    UIAlertController *alertController = [self alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

    if(cancelButtonTitle != nil) {

        UIAlertAction *cancelButton = [UIAlertAction
                                       actionWithTitle:cancelButtonTitle
                                       style:UIAlertActionStyleCancel
                                       handler:^(UIAlertAction *action)
                                       {
                                           tapBlock(alertController, ALERTACTION_CANCEL); // CANCEL BUTTON CALL BACK ACTION
                                       }];
        [alertController addAction:cancelButton];

    }

    if(otherButtonTitle != nil) {

        UIAlertAction *otherButton = [UIAlertAction
                                   actionWithTitle:otherButtonTitle
                                   style:UIAlertActionStyleDefault
                                   handler:^(UIAlertAction *action)
                                   {
                                       tapBlock(alertController, ALERTACTION_OTHER); // OTHER BUTTON CALL BACK ACTION
                                   }];

        [alertController addAction:otherButton];
    }

    [controller presentViewController:alertController animated:YES completion:nil];

    return alertController;
}

@end

在你的ViewController.m文件中

[UIAlertController showAlertIn:self WithTitle:@"" message:@"" cancelButtonTitle:@"Cancel" otherButtonTitles:@"Other" tapBlock:^(UIAlertController *alertController, NSInteger index){

 if(index == ALERTACTION_CANCEL){

 // CANCEL BUTTON ACTION
 }else
if(index == ALERTACTION_OTHER){

 // OTHER BUTTON ACTION
 }

 [alertController dismissViewControllerAnimated:YES completion:nil];

 }];

注意:如果您想添加超过两个按钮,则需在UIAlertController中再添加一个UIAlertAction。


3
我尝试了上面的方法,但是没有一个可以显示警告视图,只有当我将 presentViewController: 方法放在 dispatch_async 语句中时才能显示:dispatch_async(dispatch_get_main_queue(), ^ { [self presentViewController:alert animated:YES completion:nil]; });。请参考“iOS 9 的 UIAlertView 替代方法?”

3

使用UIAlertController代替UIAlertView

-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert=   [UIAlertController
                              alertControllerWithTitle:title
                              message:message
                              preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){

    //do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}

1
-(void)showAlert{
    
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Title"
                                                                   message:@"Message"
                                                            preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction * action) {}];
    
    [alert addAction:defaultAction];
    [self presentViewController:alert animated:YES completion:nil];
}

[self showAlert]; // 调用方法


0

请检查:

UIAlertController *alertctrl =[UIAlertController alertControllerWithTitle:@"choose Image" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *camera =[UIAlertAction actionWithTitle:@"camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        [self Action];  //call Action need to perform 
    }];

[alertctrl addAction:camera];
-(void)Action 

{

}

0
 UIAlertController * alert = [UIAlertController
                                 alertControllerWithTitle:@"Are you sure you want to logout?"
                                 message:@""
                                 preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* yesButton = [UIAlertAction
                                actionWithTitle:@"Logout"
                                style:UIAlertActionStyleDestructive
                                handler:^(UIAlertAction * action)
                                {

                                }];

    UIAlertAction* noButton = [UIAlertAction
                               actionWithTitle:@"Cancel"
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * action) {
                                   //Handle no, thanks button
                               }];

    [alert addAction:noButton];
    [alert addAction:yesButton];

    [self presentViewController:alert animated:YES completion:nil];

这只是@Adnan Aftab帖子的转载。 - Steve A

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