使用块回调自定义UIAlertView

时间:2012-12-28 01:18:29

标签: ios block uialertview objective-c-blocks

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

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

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

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

7 个答案:

答案 0 :(得分: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];

答案 1 :(得分: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);
};

答案 2 :(得分: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];

我希望它会对你有所帮助。

答案 3 :(得分: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#>]

值&lt;#^(int intBlock)完成#&gt;会像这样出现泡泡。

enter image description here

当您按下输入值时,它将填写阻止您使用。

[myCustomAlert setCompletion:^(int selectedButtonIndex) {

}

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

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

希望能够解决并发症。

答案 4 :(得分:0)

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

https://github.com/sourabhverma/LMSVBlocks

概念:要使UIAlertView块兼容,您需要另一个类(Say 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;
}

<强>最后 希望你发现它很有用..

答案 5 :(得分: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

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

答案 6 :(得分: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)
        }
    }
}