¿Cómo escribir manejadores de events para botones en UIAlertView?

Diga que tengo una vista de alerta como sigue en obj c

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:@"download"]; [alert show]; [alert release]; 

Ahora tenemos 2 botones en la vista de alerta (Ok & Download), ¿cómo escribir un controller de events para el Download?

Primero necesitará agregar UIAlertViewDelegate a su file de encabezado como a continuación:

Archivo de encabezado (.h)

 @interface YourViewController : UIViewController<UIAlertViewDelegate> 

Archivo de implementación (.m)

 UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:@"download"]; [alert show]; [alert release]; - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 0) { //Code for OK button } if (buttonIndex == 1) { //Code for download button } } 

Ahora que la mayoría de los dispositivos iOS tienen versiones firmare con bloques de soporte, es un anacronismo usar la torpe API de callback para manejar las presiones de los botones. Los bloques son el path a seguir, vea, por ejemplo, las classs de alerta de Lambda en GitHub :

 CCAlertView *alert = [[CCAlertView alloc] initWithTitle:@"Test Alert" message:@"See if the thing works."]; [alert addButtonWithTitle:@"Foo" block:^{ NSLog(@"Foo"); }]; [alert addButtonWithTitle:@"Bar" block:^{ NSLog(@"Bar"); }]; [alert addButtonWithTitle:@"Cancel" block:NULL]; [alert show]; 

Declare sus UIAlertViews como se sabe.

 UIAlertView *alertLogout=[[UIAlertView alloc]initWithTitle:@"Title" message:@"Stop Application?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; [alertLogout show]; [alertLogout release]; 

establecer delegado en uno mismo e implementar este método.

 -(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if(actionSheet== alertLogout) {//alertLogout if (buttonIndex == 0){ }else if(buttonIndex==1){ } }else if (actionSheet==alertComment) {//alertComment if (buttonIndex==0) { } } } 

La respuesta de Stack y Guillermo Ortega es probablemente lo que usaría con un par de UIAlertView pero no por diez. Yo uso BlocksKit, que es similar a Lambda, que es lo que sugirió el alma. Esa es una buena opción también, aunque si tiene demasiados bloques nesteds, comenzará a ver los desaciertos (aparte del hecho de que dependerá de otra biblioteca).

La forma habitual de manejar varias cosas sería tener un object controller. ( @interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end ) hace que ese object sea el delegado de la vista de alerta y se asegure de que el object esté vivo al less hasta que se elimine la vista de alerta. Esto ciertamente funcionará, pero podría ser demasiado trabajo …

Lo que sigue es lo que se me ocurrió; IMO es más simple y no hay necesidad de ninguna biblioteca thirdParty, ni un ivar por UIAlertView. Solo un object adicional ( @property (nonatomic, strong) NSArray *modalActions ) para almacenar las acciones que hará UIAlertView actual para realizar

Mostrar una UIAlertView y reactjsr en consecuencia.

 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:alertTitle message:@"Blah blah" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:b1, b2, b3, nil]; // Add one selector/action per button at the proper index self.modalActions = @[ [NSNull null], // Because indexes of UIAlertView buttons start at 1 NSStringFromSelector(@selector(actionForAlertViewButton1)), NSStringFromSelector(@selector(actionForAlertViewButton2)), NSStringFromSelector(@selector(actionForAlertViewButton3))]; [alertView show]; 

El método delegado:

 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { if (alertView.cancelButtonIndex != buttonIndex) { [self performModalActionAtIndex:buttonIndex]; } } 

La parte que realmente realiza la acción:

 - (void)performModalActionAtIndex:(NSInteger)index { if (-1 < index && index < self.modalActions.count && [self.modalActions[index] isKindOfClass:[NSString class]]) { SEL action = NSSelectorFromString(self.modalActions[index]); NSLog(@"action: %@", self.modalActions[index]); if ([self respondsToSelector:action]) { // There is a situation with performSelector: in ARC. // http://stackoverflow.com/questions/7017281/ #pragma clang diagnostic push #pragma clang diagnostic ignonetworking "-Warc-performSelector-leaks" [self performSelector:action]; #pragma clang diagnostic pop } self.modalActions = nil; } 

Reutilizable para UIActionSheets también

 UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:cancelButton destructiveButtonTitle:nil otherButtonTitles:button1, button2, button3, nil]; // Similarly, add one action per button at the proper index self.modalActions = @[ NSStringFromSelector(@selector(actionForActionSheetButton1)), NSStringFromSelector(@selector(actionForActionSheetButton2)), NSStringFromSelector(@selector(actionForActionSheetButton3))]; 

El método delegado:

 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if (actionSheet.cancelButtonIndex != buttonIndex) { [self performModalActionAtIndex:buttonIndex]; } } 

Por qué esto funciona:

Esto funciona por dos razones:

Primero, nunca presento dos UIAlertView que tienen un delegado al mismo time. (IMO no debería, no se ve bien). Segundo, porque en mi caso (como el 90% de los casos) el objective de las acciones es siempre el mismo object (en este caso: self ). Incluso si no cumple con las condiciones anteriores, incluso puede usar este enfoque con algunas modificaciones:

  • Si muestra dos o más UIAlerViews o UIActionSheets al mismo time (posible en el iPad) Utilice un dictionary para almacenar una serie de acciones asociadas con un determinado UIAlertView / UIActionSheet.

  • Si el objective de las acciones no es self , deben almacenar pares (objective y acción) en la matriz. (Algo para simular UIButtons addTarget:action:... ).

En cualquier caso, para almacenar el objective y / o UIActionSheet / UIAlertView [NSValue valueWithNonretainedObject:] debería ser útil 🙂

 First of all you declare UIAlertViewDelegate in .h file after put below code in .m file - (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 1) { //put button action which you want. } } 

Implementar UIAlertViewDelegate y hacer uso del método de delegado

 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if(buttonIndex == 0) { // Do something } else { // Do something } } 
 UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"Data Saved" message:@"Choose more photos" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:Nil]; [alertView show]; [alertView release]; -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if(buttonIndex==0) { [self dismissModalViewControllerAnimated:YES]; } } 

en swift: podemos usar este pequeño bloque de código

  let alert = UIAlertController(title: "Alert", message: "This is an alert message", prefernetworkingStyle: UIAlertControllerStyle.Alert) let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(action:UIAlertAction) in print("This is in alert block") }) alert.addAction(action) self.presentViewController(alert, animated: true, completion: nil)