0

我最近刚刚实现:https ://github.com/gpambrozio/BlockAlertsAnd-ActionSheets

我已将所有必要的文件导入到我的应用程序中并且编译良好。现在的问题是,我该如何处理逻辑变化?

所以在使用 Apple 的 UIAlertView 之前,我做了这样的事情:

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Which Key?" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
            for (NSMutableDictionary *dict in myArray) {
                [alertView addButtonWithTitle:[dict objectForKey:@"Key"]];
            }
 [alertView show];
 [alertView release];

然后在 alertview 的回调中我会这样做:

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    [[Singleton sharedSingleton] setKey:buttonIndex];
}

现在BlockAlertView没有回调哪个按钮被按下了,他们如何处理按钮按下是把你想要执行的代码放在我下面显示的块中。无论如何,这就是类似的 BlockAlertView 的外观:

BlockAlertView *alertView = [BlockAlertView alertWithTitle:@"Which Key?" message:nil];
            for (NSMutableDictionary *dict in myArray) {
                [alertView addButtonWithTitle:[dict objectForKey:@"Key"] block:^{
                    //Not sure what to do here
                }];
            }
[alertView show];

现在这是我不知道该怎么做的事情,在那个块中,我如何使用 Apple 的原生 UIAlertView 实现我之前所做的事情?我无法访问按钮索引,也无法访问按钮的名称(因为我需要索引,所以无论如何这对我的情况有帮助)

无论如何,我应该如何继续使用 Apple 的原生 UIAlertView 但使用 BlockAlertView 的逻辑?

谢谢!

Edit1 @Christian Pappenberger:

这是 BlockAlertView 的 .h,除非我错了,否则我认为没有可以添加的协议。这里是:

@interface BlockAlertView : NSObject {
@protected
    UIView *_view;
    NSMutableArray *_blocks;
    CGFloat _height;
}

+ (BlockAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message;

- (id)initWithTitle:(NSString *)title message:(NSString *)message;

- (void)setDestructiveButtonWithTitle:(NSString *)title block:(void (^)())block;
- (void)setCancelButtonWithTitle:(NSString *)title block:(void (^)())block;
- (void)addButtonWithTitle:(NSString *)title block:(void (^)())block;

- (void)show;
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated;

@property (nonatomic, retain) UIImage *backgroundImage;
@property (nonatomic, readonly) UIView *view;
@property (nonatomic, readwrite) BOOL vignetteBackground;

@end
4

2 回答 2

3

A block is a portion of code that will be executed once it is triggered.

[alertView addButtonWithTitle:[dict objectForKey:@"Key"] block:^{
                    //Not sure what to do here
                }];

The code above adds a button to the BlockAlertView and once it is pressed, the code that's in the block it's what is going to be executed. Here's an example:

...

[alertView addButtonWithTitle:@"First Button" block:^{
                    NSLog(@"First Button Pressed");
                }];

[alertView addButtonWithTitle:@"Second Button" block:^{
                    NSLog(@"Second Button Pressed");
                }];
...

[alertView show];

Once the code is executed and the alertView is shown, two buttons will be present in the alertView, with titles "First Button" and "Second Button". When you click each of the buttons, what will happen is that the code in the block will be executed. The console will output "First Button Pressed" or "Second Button Pressed" depending on the button pressed.

Now that you know how this type of alertViews work I'll explain what you need to do in your case.

As you point out you wont get the buttonIndex, but you will know which button triggered the block.

So if you need to now the buttonIndex I would add an int buttonIndex and increment it each time as in the code below:

BlockAlertView *alertView = [BlockAlertView alertWithTitle:@"Which Key?" message:nil];

    int buttonIndex = 0; // HERE

    for (NSMutableDictionary *dict in myArray) {
       [alertView addButtonWithTitle:[dict objectForKey:@"Key"] block:^{
                [[Singleton sharedSingleton] setKey:buttonIndex]; // HERE
           }];

    buttonIndex++; // HERE
                    }

        [alertView show];

If you need further explanation of something else feel free to ask.

EDIT Added explanation

The block paradigm differs with the delegate paradigm. With the delegate paradigm when the button is pressed it will call the delegate method (clickedButtonAtIndex:) in the UIAlerViewDelegate case. When a block gets executed, each separate block is triggered.

Here's the key:

When you use the block approach each button owns the code it will execute once its triggered. In the delegate approach when buttons are pressed they will call a common method to be executed.

So in an example:

Goal: Output to the console different words depending on the button pressed.

Delegate approach:

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Which Key?" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil];

[alertView addButtonWithTitle:"@Button 1"];
[alertView addButtonWithTitle:"@Button 2"];
[alertView addButtonWithTitle:"@Button 3"];

[alertView show];

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if(buttonIndex == 0)
       NSLog(@"Dog");
    else if (buttonIndex == 1)
       NSLog(@"Cat");
    else if (buttonIndex == 2)
       NSLog(@"Shark");
}

As you can see, once the button is pressed, the delegate method is called and there is when you decide depending on the buttonIndex what to output.

Block approach:

BlockAlertView *alertView = [BlockAlertView alertWithTitle:@"Which Key?" message:nil];

[alertView addButtonWithTitle:@"Button 1" block:^{
                    NSLog(@"Dog");
                }];
[alertView addButtonWithTitle:@"Button 2" block:^{
                    NSLog(@"Cat");
                }];          
[alertView addButtonWithTitle:@"Button 3" block:^{
                    NSLog(@"Shark");
                }];

[alertView show];

In this case no delegate method is called, and the execution code is inside each button! So you don't need to "check for specific button title strings and do code based upon that". You need to include the code that will be executed in each button.

I dont know if i'm clear, if you need further explanation feel free to ask.

于 2012-08-05T21:05:58.377 回答
0

你检查是否有协议实现者?

于 2012-08-05T20:53:28.433 回答