我开发了这个类,它基本上是一个带有在块上运行的输入字段的UIAlertView。因此,无论用户在alertView上做什么(单击取消,确定或填充文本),都会返回到块:
标题
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
@interface AlertViewBlocoComInput : NSObject
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
@end
实施
@interface AlertComBloco : UIAlertView
@property (nonatomic, copy) onClickBlock runOnClickBlock;
@end
@implementation AlertComBloco
@end
@interface AlertViewBlocoComInput () <UIAlertViewDelegate>
@end
@implementation AlertViewBlocoComInput
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
AlertComBloco *alerta = [[AlertComBloco alloc] initWithTitle:titulo
message:mensagem
delegate:self
cancelButtonTitle:tituloCancel
otherButtonTitles:nil];
alerta.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[alerta addButtonWithTitle:umOutroBotao];
}
[alerta setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [alerta textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
[alerta show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
AlertComBloco *alerta = (AlertComBloco *)alertView;
onClickBlock bloco = alerta.runOnClickBlock;
UITextField *input = [alertView textFieldAtIndex:0];
if (bloco) {
bloco(buttonIndex, input.text);
}
}
@end
我运行它,它显示带有消息的alertView,占位符,完美。我单击取消或填写文本并按确定,从不触发alertview:clickedButtonAtIndex:
。我不明白为什么。
感谢
答案 0 :(得分:2)
您可以直接将UIAlertView子类化并添加自己的初始化程序。我已将您的类抽象为UIAlertView的单个子类,它工作正常。请参阅下面的帖子,
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
@interface AlertComBloco : UIAlertView<UIAlertViewDelegate>
@property (nonatomic, copy) onClickBlock runOnClickBlock;
@end
@implementation AlertComBloco
- (id)initWithTitulo:(NSString *)titulo mensagem:(NSString*)mensagem tituloBotaoCancel:(NSString*)tituloCancel outrosBotoesArray:(NSArray *)titulosOutrosBotoes inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco{
if(self = [self initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil, nil]){
_runOnClickBlock = bloco;
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UITextField *input = [alertView textFieldAtIndex:0];
if (self.runOnClickBlock) {
self.runOnClickBlock(buttonIndex, input.text);
}
}
@end
然后,您可以使用视图控制器中的块来调用它,就像这样,
- (void)showAlert:(id)sender{
AlertComBloco *alertCombo = [[AlertComBloco alloc] initWithTitulo:@"Hi" mensagem:@"Custom Alert" tituloBotaoCancel:@"Cancel" outrosBotoesArray:@[@"Other"] inputComPlaceHolder:@"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
NSLog(@"Button at index %ld, with text %@", (long)buttonIndex, textoInput);
}];
[alertCombo show];
}
答案 1 :(得分:1)
您没有向我们展示您是如何调用它的,但很可能您的AlertViewBlocoComInput
是一个超出范围的局部变量,因此在用户完成输入之前被释放。您可以通过临时添加dealloc
方法来证明这一点,该方法将告诉您何时取消分配对象。
- (void)dealloc {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
在修复此问题方面,您可以将AlertViewBlocoComInput
实例设为类属性,因此在手动nil
之前不会释放它。或者,您可以AlertViewBlocoComInput
在调用clickedButtonAtIndex
之前保持对自身的强引用。
或者,最简单,利用UIAlertView
已经保留的事实,因此您可以完全退出AlertComBloco
,将其折叠为AlertViewBlocoComInput
:
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
@interface AlertViewBlocoComInput : UIAlertView <UIAlertViewDelegate>
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
@property (nonatomic, copy) onClickBlock runOnClickBlock;
@end
@implementation AlertViewBlocoComInput
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
self = [super initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil];
if (self) {
self.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (self.runOnClickBlock) {
UITextField *input = [alertView textFieldAtIndex:0];
self.runOnClickBlock(buttonIndex, input.text);
}
}
@end
你会这样称呼它:
AlertViewBlocoComInput *obj = [[AlertViewBlocoComInput alloc] initComTitulo:@"title" mensagem:@"message" tituloBotaoCancel:@"OK" outrosBotoesArray:nil inputComPlaceHolder:@"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
// do whatever you want with `buttonIndex` and `textoInput` here
//
// NSLog(@"%ld %@", (long)buttonIndex, textoInput);
}];
[obj show];