Ios 带有块回调的自定义UIAlertView

Ios 带有块回调的自定义UIAlertView,ios,block,uialertview,objective-c-blocks,Ios,Block,Uialertview,Objective C Blocks,MyAlertView(UIAlertView的子类)具有以下方法: - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (self.clickedButtonAtIndexBlock != NULL) self.clickedButtonAtIndexBlock(buttonIndex); } 我的问题是在创建警报视图时如何定义回调?显然

MyAlertView(UIAlertView的子类)具有以下方法:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (self.clickedButtonAtIndexBlock != NULL)
        self.clickedButtonAtIndexBlock(buttonIndex);
}
我的问题是在创建警报视图时如何定义回调?显然这是错误的:

alert.clickedButtonAtIndexBlock = ^{
    NSLog(@"clicked: %d", buttonIndex);
}

尝试这样做(我还没有测试过):


尝试这样做(我还没有测试过):

试试这个

假设您创建了一个名为MyCustomAlert的类,并将其声明为此变量

MyCustomAlert *myCustomAlert = [[MyCustomAlent alloc] init];
您可以将其放在头文件中

- (void)setCompletion:(void (^)(int selectedButtonIndex))completion;
你可以把它放在你的实现文件中

typedef void (^IntBlock)(int intBlock);
IntBlock _completion;

- (void)setCompletion:(void (^)(int selectedButtonIndex))completion{
    _completion = completion;
}
现在在您声明“myCustomAlert”的项目中。如果你输入

[myCustomAlert setCompletion: // And select the autocomplete item
你最终会得到这个

[myCustomAlert setCompletion:<#^(int intBlock)completion#>]
当您想在自定义类中触发_completion块时,您可以在代码中的某个地方调用它,如下所示

- (void) callCompletionWithButtonIndex:(int) index{
    if (_completion != nil) _completion(index);
}
希望这能消除并发症。

试试这个

假设您创建了一个名为MyCustomAlert的类,并将其声明为此变量

MyCustomAlert *myCustomAlert = [[MyCustomAlent alloc] init];
您可以将其放在头文件中

- (void)setCompletion:(void (^)(int selectedButtonIndex))completion;
你可以把它放在你的实现文件中

typedef void (^IntBlock)(int intBlock);
IntBlock _completion;

- (void)setCompletion:(void (^)(int selectedButtonIndex))completion{
    _completion = completion;
}
现在在您声明“myCustomAlert”的项目中。如果你输入

[myCustomAlert setCompletion: // And select the autocomplete item
你最终会得到这个

[myCustomAlert setCompletion:<#^(int intBlock)completion#>]
当您想在自定义类中触发_completion块时,您可以在代码中的某个地方调用它,如下所示

- (void) callCompletionWithButtonIndex:(int) index{
    if (_completion != nil) _completion(index);
}

希望这能解决这个复杂问题。

我编写了一个简单的类LMSVBlocks,它可以在一行中轻松显示警报和获取块回调。希望您会发现它在这方面很有用

概念:要使UIAlertView块兼容,您需要另一个类(如LMSVBlockAlert)来处理委托方法,并且当UIAlertView委托将发出回调时,LMSVBlockAlert类可以在块中发送回调

代码: (LMSVBlockAlert.m)

在一个数组中维护LMSVBlockAlert的所有实例,以便它们具有强引用

static NSMutableArray *_LMSVblockHandlersArray = nil;
将块处理程序保持在LMSVBlockAlert中

@interface LMSVBlockAlert() <UIAlertViewDelegate>
@property (nonatomic, copy) void (^cancelCompletionBlock)();
@property (nonatomic, copy) void (^confirmCompletionBlock)();
@end
当在LMSVBlockAlert中触发警报委托时,向block发送回调并从内存中清除

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

    switch (buttonIndex) {
        case 0://Cancel
        {
            if(_cancelCompletionBlock){
                _cancelCompletionBlock();
            }
        }
            break;
        case 1://OK
        {
            if(_confirmCompletionBlock){
                _confirmCompletionBlock(alertView);
            }
        }
            break;
        default:
            break;
    }
    [_LMSVblockHandlersArray removeObject:self];
}
现在您可以有两个简单的方法,可以为您提供UIAlertView回调

+(LMSVBlockAlert*)newInstance{
    LMSVBlockAlert *newIns = [[LMSVBlockAlert alloc] init];
    [LMSVBlockAlert updateHandlerArrayWith:newIns];
    return newIns;
}
+(UIAlertView*)promptAlertTwoBtn:(NSString*)msg title:(NSString*)title onCancel:(void (^)())onCancel onConfirm:(void (^)())onConfirm{

    return [[LMSVBlockAlert newInstance] showAlertMainWithTitle:title msg:msg onCancel:^{
        onCancel();
    } onConfirm:^(UIAlertView *alertView) {
        onConfirm();
    }];
}

-(UIAlertView*)showAlertMainWithTitle:(NSString*)title msg:(NSString*)msg onCancel:(void (^)())onCancel onConfirm:(void (^)(UIAlertView*))onConfirm{

    UIAlertView *newAlert = nil;


    newAlert = [[UIAlertView alloc]
                    initWithTitle:title
                    message:msg
                    delegate:self
                    @"Cancel"
                    otherButtonTitles:@"Confirm", nil];


    [newAlert show];

    self.cancelCompletionBlock = onCancel;
    self.confirmCompletionBlock = onConfirm;

    return newAlert;
}
最后
希望您觉得它很有用。

我编写了一个简单的类LMSVBlocks,可以在一行中轻松显示警报和获取块回调。希望您会发现它在这方面很有用

概念:要使UIAlertView块兼容,您需要另一个类(如LMSVBlockAlert)来处理委托方法,并且当UIAlertView委托将发出回调时,LMSVBlockAlert类可以在块中发送回调

代码: (LMSVBlockAlert.m)

在一个数组中维护LMSVBlockAlert的所有实例,以便它们具有强引用

static NSMutableArray *_LMSVblockHandlersArray = nil;
将块处理程序保持在LMSVBlockAlert中

@interface LMSVBlockAlert() <UIAlertViewDelegate>
@property (nonatomic, copy) void (^cancelCompletionBlock)();
@property (nonatomic, copy) void (^confirmCompletionBlock)();
@end
当在LMSVBlockAlert中触发警报委托时,向block发送回调并从内存中清除

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

    switch (buttonIndex) {
        case 0://Cancel
        {
            if(_cancelCompletionBlock){
                _cancelCompletionBlock();
            }
        }
            break;
        case 1://OK
        {
            if(_confirmCompletionBlock){
                _confirmCompletionBlock(alertView);
            }
        }
            break;
        default:
            break;
    }
    [_LMSVblockHandlersArray removeObject:self];
}
现在您可以有两个简单的方法,可以为您提供UIAlertView回调

+(LMSVBlockAlert*)newInstance{
    LMSVBlockAlert *newIns = [[LMSVBlockAlert alloc] init];
    [LMSVBlockAlert updateHandlerArrayWith:newIns];
    return newIns;
}
+(UIAlertView*)promptAlertTwoBtn:(NSString*)msg title:(NSString*)title onCancel:(void (^)())onCancel onConfirm:(void (^)())onConfirm{

    return [[LMSVBlockAlert newInstance] showAlertMainWithTitle:title msg:msg onCancel:^{
        onCancel();
    } onConfirm:^(UIAlertView *alertView) {
        onConfirm();
    }];
}

-(UIAlertView*)showAlertMainWithTitle:(NSString*)title msg:(NSString*)msg onCancel:(void (^)())onCancel onConfirm:(void (^)(UIAlertView*))onConfirm{

    UIAlertView *newAlert = nil;


    newAlert = [[UIAlertView alloc]
                    initWithTitle:title
                    message:msg
                    delegate:self
                    @"Cancel"
                    otherButtonTitles:@"Confirm", nil];


    [newAlert show];

    self.cancelCompletionBlock = onCancel;
    self.confirmCompletionBlock = onConfirm;

    return newAlert;
}
最后
希望您发现它很有用。

您可以从github简单地使用这些类别类

这为AlertView和action Sheet提供了关闭块

例如

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"AlertView+Block" message:@"WithBlocks" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"newAlertViewWithTextFields",@"newAlertViewWithSingleTextField", nil];
[alert showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex) 
{ if (buttonIndex == 0) { } else if (buttonIndex == 1) { } }];
除此之外,它还为文本字段提供方法

-(void) showWithFinishBlock:(FinishBlock_)block_; //-- AlertView with TextField [simple or secure]

-(void) showWithTextFieldBlock:(TextFieldBlock_)block_ secure:(BOOL)isSecure; //-- AlertView with two textfields username & password
您可以看看附带的示例。
我希望它能对您有所帮助。

您可以从github简单地使用这些类别类

这为AlertView和action Sheet提供了关闭块

例如

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"AlertView+Block" message:@"WithBlocks" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"newAlertViewWithTextFields",@"newAlertViewWithSingleTextField", nil];
[alert showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex) 
{ if (buttonIndex == 0) { } else if (buttonIndex == 1) { } }];
除此之外,它还为文本字段提供方法

-(void) showWithFinishBlock:(FinishBlock_)block_; //-- AlertView with TextField [simple or secure]

-(void) showWithTextFieldBlock:(TextFieldBlock_)block_ secure:(BOOL)isSecure; //-- AlertView with two textfields username & password
您可以看看附带的示例。
我希望它能对您有所帮助。

我写了一篇博客文章,介绍了如何(以及为什么)将块回调添加到警报视图、动作表和动画中:

如果您只想实现此功能,可以从GitHub下载源文件:

用法:

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"My easy alert"  
                                                message:@"Would you like to perform some kind of action?"
                                      cancelButtonTitle:@"No"
                                      otherButtonTitles:@"Yes", nil];
[alert setHandler:^(UIAlertView* alert, NSInteger buttonIndex) {
    NSLog(@"Perform some kind of action");
} forButtonAtIndex:[alert firstOtherButtonIndex]];
[alert show];

我写了一篇关于如何(以及为什么)将块回调添加到警报视图、动作表和动画的博客文章:

如果您只想实现此功能,可以从GitHub下载源文件:

用法:

UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"My easy alert"  
                                                message:@"Would you like to perform some kind of action?"
                                      cancelButtonTitle:@"No"
                                      otherButtonTitles:@"Yes", nil];
[alert setHandler:^(UIAlertView* alert, NSInteger buttonIndex) {
    NSLog(@"Perform some kind of action");
} forButtonAtIndex:[alert firstOtherButtonIndex]];
[alert show];

我已经用Swift写了一个简单的扩展,希望对你有所帮助

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)
        }
    }
}

我已经用Swift写了一个简单的扩展,希望对你有所帮助

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)
        }
    }
}
检查这个,我在几个项目中使用过它,对我很好。以下是示例:

OpinionzAlertView *alert = [[OpinionzAlertView alloc] initWithTitle:@"title"
                                                            message:@"message"
                                                  cancelButtonTitle:@"No, thanks"
                                                  otherButtonTitles:@[@"Done"]
                                            usingBlockWhenTapButton:^(OpinionzAlertView *alertView, NSInteger buttonIndex) {

                                                NSLog(@"buttonIndex: %li", (long)buttonIndex);
                                                NSLog(@"buttonTitle: %@", [alertView buttonTitleAtIndex:buttonIndex]);
                                            }];
[alert show];
我希望它能对您有所帮助。

检查一下,我已经在几个项目中使用过它,对我很有用。以下是示例:

OpinionzAlertView *alert = [[OpinionzAlertView alloc] initWithTitle:@"title"
                                                            message:@"message"
                                                  cancelButtonTitle:@"No, thanks"
                                                  otherButtonTitles:@[@"Done"]
                                            usingBlockWhenTapButton:^(OpinionzAlertView *alertView, NSInteger buttonIndex) {

                                                NSLog(@"buttonIndex: %li", (long)buttonIndex);
                                                NSLog(@"buttonTitle: %@", [alertView buttonTitleAtIndex:buttonIndex]);
                                            }];
[alert show];

我希望这将对您有所帮助。

在这个回答中,您没有显示您所引用的头文件/实现文件。您还引入了自定义警报概念,但没有解释它如何适合解决方案。这迫使读者猜测你的意图(这总是不好的)。答案可以通过解决这些错失的机会来改进,我指的是你的头文件和实现文件,而不是我的。因此,我无法向您提供一个,因为这意味着要放入您的代码中。。但你是对的,我没有提供完成电话。我已经补充了这一点。当您提到头文件和实现文件时,这两者是如何结合的?它是视图控制器还是自定义警报的子类?如果我先前的要求不清楚,很抱歉。我可以简单地假设是后者,但具体性总是更好的。头文件和实现文件是.h和.m文件,它们是您希望使用此函数指针的类的文件。可以将UIAlertView子类化,可以创建AlertManager,可以将其放在ViewController上,这取决于您想要做什么。这些信息仅仅显示了如何实现回调函数,以便您可以创建回调,使用回调函数,以及如何允许编辑器为您提供块本身:)在这个回答中,您没有显示所引用的头文件/实现文件。您还引入了自定义警报con