119

I have tried several ways to use UIAlertController,instead of UIAlertView. I tried several ways but I cannot make the alert action work. Here is my code that works fine in IOS 8 and IOS 9 but is showing up with deprecated flags. I tried the elegant suggestion below but I can't make it function in this context. I need to submit my app and this is the last thing to address. Thank You for any further suggestions. I am a newbie.

#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];

        }

}
Ketan P
  • 4,259
  • 3
  • 30
  • 36
Bux
  • 1,273
  • 2
  • 9
  • 9
  • 1
    Question not clear. What is it that you want ? – Moumou Sep 21 '15 at 08:07
  • UIAlertView is deprecated in IOS 9 and we have to use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead. However, the alert does not show when I use UIAlertController methods. I tried the solution below, but still the alert view does not show.. Thank you.. – Bux Sep 21 '15 at 11:54
  • Okay. Can you show what you have done and that doesn't work ? – Moumou Sep 21 '15 at 12:00
  • 1
    After presenting you are calling [self dismissViewControllerAnimated:true completion:nil]; which will dismiss alert controller – Adnan Aftab Sep 22 '15 at 20:39
  • Yes.. I pasted the old code and pressed the tab button while editing message. I am new to Stack ... I still cannot get my code to work correctly with the UIAlertController class. My Complete code is: – Bux Sep 23 '15 at 08:58
  • 3
    This is an important question in the sense that UIAlertController is pretty new and many developers will be worried about the deprecation. The unreasonable down votes have bad effect on a valid question. Those who down voted the question should have changed their vote after the edit. But then,"down vote trolls" who get a badge for their down vote do not do this anyway. The SO moderators should have a way to fix it. – Totoro Dec 17 '15 at 01:29
  • https://stackoverflow.com/questions/24022479/how-would-i-create-a-uialertview-in-swift – Naresh Sep 24 '19 at 05:09

10 Answers10

250

From iOS8 Apple provide new UIAlertController class which you can use instead of UIAlertView which is now deprecated, it is also stated in deprecation message:

UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead

So you should use something like this

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];
Adnan Aftab
  • 14,377
  • 4
  • 45
  • 54
  • 2
    Thank you for your fast reply.. I tried this, but the alert view does not show.. Nor does it when I add my yes please action. – Bux Sep 21 '15 at 11:56
  • 1
    Can you show me your code, because its working fine for me, make sure you are executing this code on main thread – Adnan Aftab Sep 21 '15 at 12:25
  • can you add your code inside question, that would be better every one can see that – Adnan Aftab Sep 21 '15 at 12:49
  • Hi, I added my complete code that works in IOS8 and IOS9, but is flagged deprecated. I tried several ways to implement your code but the alert does not show, and the action to open the store ViewController, will not function. Thank you for your help. – Bux Sep 23 '15 at 09:16
  • I think it's better to remove this line `[alert dismissViewControllerAnimated:YES completion:nil];` from the actions handlers, because the alert hides automatically without this code. Moreover, one can mistakenly put code in the completion block which will not be executed. Cheers :) – stellz Jan 18 '16 at 11:02
  • But In older UIAlertView I can show them in whatever place I wish to show, But Here I need a UIViewController to display the alert – vignesh kumar Mar 17 '16 at 17:38
  • @vignesh kumar if you want to use the new theme outside of a view controller use: UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(...) – Ali Beadle May 30 '16 at 13:11
  • @AliBeadle Thanks for the reply.just asking as I am handling an old project in which they show uialert from uitableviewcell (even thought it is bad way) – vignesh kumar May 31 '16 at 05:09
23
//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];
}

If you want to use this alert in NSObject class you should use like:

-(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:^{
    }];
});
}
Mannam Brahmam
  • 2,225
  • 2
  • 24
  • 36
14

Swift version of new implementation is :

 let alert = UIAlertController(title: "Oops!", message:"your message", preferredStyle: .Alert)
 alert.addAction(UIAlertAction(title: "Okay.", style: .Default) { _ in })
 self.presentViewController(alert, animated: true){}
Dashrath
  • 2,141
  • 1
  • 28
  • 33
11

Xcode 8 + Swift

Assuming self is a 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
    }
}
Community
  • 1
  • 1
SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
7

Make UIAlertController+AlertController Category as:

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

in your 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];

 }];

NOTE: If you want to add more than two buttons then add another more UIAlertAction to the UIAlertController.

Suhas Arvind Patil
  • 1,732
  • 1
  • 19
  • 31
3

Use UIAlertController instead of 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];
}
Mahesh reddy
  • 134
  • 13
3

I tried the above methods, and no one can show the alert view, only when I put the presentViewController: method in a dispatch_async sentence:

dispatch_async(dispatch_get_main_queue(), ^ { [self presentViewController:alert animated:YES completion:nil]; });

Refer to Alternative to UIAlertView for iOS 9?.

Community
  • 1
  • 1
HongchaoZhang
  • 3,494
  • 1
  • 17
  • 8
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]; // calling Method

uplearned.com
  • 3,393
  • 5
  • 44
  • 59
0

Check this:

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 

{

}
Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67
Sabby
  • 403
  • 3
  • 15
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];
Ishwar Hingu
  • 562
  • 7
  • 14