UIAlertView primer IOS 9 obsoleto

108

He probado varias formas de usar UIAlertController, en lugar de UIAlertView. Intenté de varias formas pero no puedo hacer que la acción de alerta funcione. Aquí está mi código que funciona bien en IOS 8 e IOS 9, pero aparece con indicadores obsoletos. Probé la elegante sugerencia a continuación, pero no puedo hacer que funcione en este contexto. Necesito enviar mi aplicación y esto es lo último que debo abordar. Gracias por cualquier otra sugerencia. Soy un novato

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

        }

}
Bux
fuente
1
Pregunta no clara. Qué es lo que quieres ?
Moucheg
UIAlertView está obsoleto en IOS 9 y tenemos que usar UIAlertController con un estilo preferido de UIAlertControllerStyleAlert en su lugar. Sin embargo, la alerta no se muestra cuando utilizo los métodos UIAlertController. Probé la solución a continuación, pero aún no aparece la vista de alerta. Gracias ..
Bux
Bueno. ¿Puedes mostrar lo que has hecho y eso no funciona?
Moucheg
1
Después de la presentación, está llamando a [autodespedidoViewControllerAnimated: finalización verdadera: nula]; que descartará el controlador de alerta
Adnan Aftab
1
Esta es una pregunta importante en el sentido de que UIAlertController es bastante nuevo y muchos desarrolladores estarán preocupados por la desaprobación. Los votos negativos irrazonables tienen un efecto negativo en una pregunta válida. Aquellos que votaron en contra de la pregunta deberían haber cambiado su voto después de la edición. Pero entonces, los "trolls de voto negativo" que obtienen una insignia por su voto negativo no hacen esto de todos modos. Los moderadores de SO deberían tener una forma de solucionarlo.
Totoro

Respuestas:

237

Desde iOS8, Apple proporciona una nueva UIAlertControllerclase que puede usar en lugar de UIAlertView, que ahora está en desuso, también se indica en el mensaje de obsolescencia:

UIAlertView está en desuso. Utilice UIAlertController con un estilo preferido de UIAlertControllerStyleAlert en su lugar

Entonces deberías usar algo como esto

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
fuente
2
Gracias por su rápida respuesta. Intenté esto, pero la vista de alerta no se muestra. Tampoco cuando agrego mi acción sí, por favor.
Bux
¿Puede mostrarme su código, porque funciona bien para mí, asegúrese de que está ejecutando este código en el hilo principal
Adnan Aftab
¿Puede agregar su código dentro de la pregunta? Sería mejor que todos puedan ver eso
Adnan Aftab
Hola, agregué mi código completo que funciona en IOS8 e IOS9, pero está marcado como obsoleto. Probé varias formas de implementar su código, pero la alerta no se muestra y la acción para abrir la tienda ViewController no funcionará. Gracias por tu ayuda.
Bux
Creo que es mejor eliminar esta línea [alert dismissViewControllerAnimated:YES completion:nil];de los controladores de acciones, porque la alerta se oculta automáticamente sin este código. Además, se puede colocar por error un código en el bloque de finalización que no se ejecutará. Saludos :)
stellz
21
//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];
}

Si desea usar esta alerta en la clase NSObject, debe usar como:

-(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 Brahman
fuente
14

La versión rápida de la nueva implementación es:

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

Xcode 8 + Swift

Suponiendo que selfes un 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
    }
}
SwiftArquitecto
fuente
si el yo es ver como logramos esto ?.
Subin K Kuriakose
Una vista no tiene nada que ver con hacer, bueno, la lógica empresarial. Reconsidere su arquitectura para que un controlador presente vistas (MVVM o MVC)
SwiftArchitect
6

Haga que la categoría UIAlertController + AlertController sea:

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

en su 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];

 }];

NOTA: Si desea agregar más de dos botones, agregue otro UIAlertAction más al UIAlertController.

Suhas Arvind Patil
fuente
3

Utilice UIAlertController en lugar de 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
fuente
3

Probé los métodos anteriores y nadie puede mostrar la vista de alerta, solo cuando pongo el presentViewController:método en una dispatch_asyncoración:

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

Consulte ¿ Alternativa a UIAlertView para iOS 9? .

HongchaoZhang
fuente
1
 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
fuente
0

Mira esto:

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 

{

}
Sabby
fuente
0
-(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]; // método de llamada

Kishore Kumar
fuente