0

MyAlertView(UIAlertView 的子类)有这个方法:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (self.clickedButtonAtIndexBlock != NULL)
        self.clickedButtonAtIndexBlock(buttonIndex);
}

我的问题是创建警报视图时如何定义回调?显然这是错误的:

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

7 回答 7

3

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

http://blog.innovattic.com/uikitblocks/

如果您只想要一个有效的实现,您可以从 GitHub 下载源文件:

https://github.com/Innovattic/UIKit-Blocks

用法:

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];
于 2014-02-26T13:54:49.120 回答
2

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

.h
typedef void (^MyClickedIndexBlock)(NSInteger index);

@interface YouInterface : YourSuperclass
@property (nonatomic, strong) MyClickedIndexBlock clickedIndexBlock;
@end

.m
//where you have to call the block
if (self.clickedIndexBlock != nil)
    self.clickedIndexBlock(buttonIndex);

// where you want to receive the callback
alert.clickedIndexBlock = ^(NSInteger index){
    NSLog(@"%d", index);
};
于 2012-12-28T01:42:06.613 回答
1

检查这个OpinionzAlertView我在几个项目中使用过它,对我很有用。这是示例:

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];

我希望它对你有帮助。

于 2015-09-25T13:12:05.357 回答
0

试试这个

假设您创建了一个名为 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#>]

值 <#^(int intBlock)completion#> 将显示为像这样的气泡。

在此处输入图像描述

当您按回车键时,它将填写块供您使用。

[myCustomAlert setCompletion:^(int selectedButtonIndex) {

}

当您想在自定义类中触发 _completion 块时,您可以在代码中的某处调用它,如下所示。

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

希望能消除复杂性。

于 2012-12-28T01:48:55.633 回答
0

我编写了一个简单的类 LMSVBlocks 来轻松显示警报并在 1 行中获取块回调。希望您会发现它对此有用

https://github.com/sourabhverma/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

当触发新警报时,创建具有 UIAlertView 和委托回调的 LMSVBlockAlert 新实例

+(LMSVBlockAlert*)newInstance{
    LMSVBlockAlert *newIns = [[LMSVBlockAlert alloc] init];
    [LMSVBlockAlert updateHandlerArrayWith:newIns];
    return newIns;
}

当在 LMSVBlockAlert 中触发警报委托时,发送回调以阻止并从内存中清除它

- (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 回调

+(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;
}

最后 希望你发现它有用..

于 2014-01-11T23:17:08.993 回答
0

您可以简单地使用来自 github 的这些类别类。

Alert_ActionSheetWithBlocks

这为 AlertView 和操作表提供了 Dismiss 块。

例如。

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

您可以查看与它捆绑的示例。我希望它对你有帮助。

于 2014-01-26T04:18:25.137 回答
0

我用 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)
        }
    }
}
于 2015-02-06T03:06:10.520 回答