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!
Aquí hay otra biblioteca útil para hacer lo mismo. http://bit.ly/ichalrtvw
Código aquí: http://bit.ly/ichalertview
Echa un vistazo a esta categoría UIAlertView-Blocks en github. Yo uso esto y funciona bien.
Echa un vistazo a la categoría UIAlertView-Blocks en Github . Escribí esto y es muy fácil de usar y funciona bien.
Buena suerte.
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:
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
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
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];