style alertas iphone objective-c

iphone - alertas - Bloque para UIAlertViewDelegate



uialertcontroller styles (11)

Aquí está mi implementación, parece que es similar a la mayoría de las respuestas aquí: http://stavash.wordpress.com/2013/01/31/quick-tip-uialertview-with-a-block-callback/

Soy bastante nuevo en el objetivo C y solo estoy tratando de averiguar si puedo usar un bloque o un selector como el argumento UIAlertViewDelegate para UIAlertView, ¿y cuál es más apropiado?

He intentado lo siguiente, pero simplemente no funciona, así que no estoy seguro de si estoy en el camino correcto o no.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Checked In" message:responseString delegate:^(UIAlertView * alertView, NSInteger buttonIndex) { NSLog(@"Done!"); } cancelButtonTitle:@"OK" otherButtonTitles: nil];

¡Gracias!



Echa un vistazo a esta categoría UIAlertView-Blocks en github. Yo uso esto y funciona bien.



Esta es una actualización de la implementación de danh, que está incompleta porque no es posible agregar varios botones. Pasar un va_list a una función es un poco complicado :-)

Así que puedes hacer esto, para poder agregar múltiples botones a UIAlertView :

- (id)initWithTitle:(NSString *)title message:(NSString *)message completion:(void (^)(NSInteger buttonIndex))completion cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... { self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil ]; if(self){ _completion = completion; va_list _arguments; va_start(_arguments, otherButtonTitles); for (NSString *key = otherButtonTitles; key != nil; key = (__bridge NSString *)va_arg(_arguments, void *)) { [self addButtonWithTitle:key]; } va_end(_arguments); } return self; }

Actualización : Puede haber una mejor manera de pasar la lista de va_v a super . Me gustaría mencionar que para mí va_list s tienen algo místico para ellos :-)


Gran idea. Aquí está. Al igual que la vista de alerta, excepto que agrega una propiedad de bloque que se invoca cuando se descarta la alerta. (Editar: he simplificado este código desde la respuesta original. Esto es lo que uso ahora en los proyectos)

// AlertView.h // #import <UIKit/UIKit.h> @interface AlertView : UIAlertView @property (copy, nonatomic) void (^completion)(BOOL, NSInteger); - (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles; @end // // AlertView.m #import "AlertView.h" @interface AlertView () <UIAlertViewDelegate> @end @implementation AlertView - (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles { self = [self initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil]; if (self) { for (NSString *buttonTitle in otherButtonTitles) { [self addButtonWithTitle:buttonTitle]; } } return self; } - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { if (self.completion) { self.completion(buttonIndex==self.cancelButtonIndex, buttonIndex); self.completion = nil; } } @end

Puede ampliar esta idea para proporcionar bloques para otros métodos de delegado, pero didDismiss es el más común.

Llámalo así:

AlertView *alert = [[AlertView alloc] initWithTitle:@"Really Delete" message:@"Do you really want to delete everything?" cancelButtonTitle:@"Nevermind" otherButtonTitles:@[@"Yes"]]; alert.completion = ^(BOOL cancelled, NSInteger buttonIndex) { if (!cancelled) { [self deleteEverything]; } }; [alert show];


He escrito una extensión simple en Swift, espero que sea útil

import UIKit extension UIAlertView { func show(completion: (alertView: UIAlertView, buttonIndex: Int) -> Void){ self.delegate = AlertViewDelegate(completion: completion) self.show() } class func showInput(title: String?, message: String?, cancellable: Bool, completion: (text: String?) -> Void){ var strOK = NSLocalizedString("OK",comment: "OK") var strCancel = NSLocalizedString("Cancel",comment: "Cancel") var alert = UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: cancellable ? strCancel : strOK) alert.alertViewStyle = UIAlertViewStyle.PlainTextInput if(cancellable) { alert.addButtonWithTitle(strOK) } alert.show { (alertView, buttonIndex) -> Void in if(cancellable && alertView.cancelButtonIndex == buttonIndex) { completion(text: nil) return } completion(text: alertView.textFieldAtIndex(0)?.text) } } private class AlertViewDelegate : NSObject, UIAlertViewDelegate { var completion : (alertView: UIAlertView, buttonIndex: Int) -> Void var retainedSelf : NSObject? init(completion: (UIAlertView, Int) -> Void ) { self.completion = completion super.init() self.retainedSelf = self } func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) { var retain = self retain.retainedSelf = nil retain.completion(alertView: alertView, buttonIndex: buttonIndex) } } }


Idea increíble. Acabo de completar exactamente su idea utilizando el patrón de Categoría, ninguna subclase, llame directamente a UIAlertView. Por favor siga estos pasos:

  1. Categoría UIAlertView en archivo .h

    @interface UIAlertView (AlertWithBlock) - (void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock; - (void)setDelegateBlock:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock; + (id)alertWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles delegate:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegate; @end

  2. En archivo .m

    @implementation UIAlertView(AlertWithBlock) static char const *delegateBlockTagKey = "delegateBlockTagKey"; - (void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock { return objc_getAssociatedObject(self, delegateBlockTagKey); } - (void)setDelegateBlock:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegateBlock { objc_setAssociatedObject(self, delegateBlockTagKey, delegateBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } + (id)alertWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles delegate:(void (^)(UIAlertView *alertView, NSInteger buttonIndex))delegate { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil]; alert.delegate = alert; alert.delegateBlock = [delegate copy]; for (NSString *buttonTitle in otherButtonTitles) { [alert addButtonWithTitle:buttonTitle]; } [alert show]; return alert; } #pragma mark - Delegate -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView.delegateBlock) { alertView.delegateBlock(alertView, buttonIndex); } } @end

  3. Llama asi

    [UIAlertView alertWithTitle:@"Title" message:@"This is a message" cancelButtonTitle:@"Cancel" otherButtonTitles:@[@"Yes",@"No"] delegate:^(UIAlertView *alertView, NSInteger buttonIndex) { NSLog(@"Click at button index %ld", buttonIndex); }];

Espero que te ayude.


Simplemente use REKit . Es similar a BlocksKit, pero es más poderoso.


Tuve que editar el ejemplo de llamada un poco para detener el error de complaciente. Solo un pequeño tweak y xcode estaba feliz.

UIAlertViewBlock *alert = [[UIAlertViewBlock alloc] initWithTitle:@"hi" message:@"hi there" completion:^(BOOL canceled,NSInteger buttonIndex) { NSLog(@"canceled=%d", canceled); NSLog(@"pressed=%d", buttonIndex); } cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil]; [alert show];


Uno debe usar UIAlertController para ese enfoque como dice el documento de Apple

Un objeto UIAlertController muestra un mensaje de alerta para el usuario. Esta clase reemplaza las clases UIActionSheet y UIAlertView para mostrar alertas. Después de configurar el controlador de alertas con las acciones y el estilo que desea, preséntelo utilizando el método presentViewController: animated: completed:.

Además de mostrar un mensaje a un usuario, puede asociar acciones con su controlador de alertas para darle al usuario una forma de responder. Para cada acción que agregue usando el método addAction:, el controlador de alerta configura un botón con los detalles de la acción. Cuando el usuario toca esa acción, el controlador de alerta ejecuta el bloque que proporcionó al crear el objeto de acción. Apple docs.

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert" message:@"This is an alert." preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {}]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil];