ベストソリューションは、彼のブログ記事Painless UIAlertViewにSasmito Adibowoからです。彼は、デリゲートハンドラとしてクロージャを使用できる汎用のUIAlertViewDelegate実装であるBSAlertViewDelegateBlockを作成しました。ここで
は、あなたがそれを使用する方法は次のとおりです。
UIAlertView* alert = ...;
BSAlertViewDelegateBlock* alertDelegate = [[BSAlertViewDelegateBlock alloc] initWithAlertView:alert];
alertDelegate.didDismissWithButtonIndexBlock = ^(UIAlertView* alertView, NSInteger buttonIndex)
{
switch (buttonIndex)
{
...
}
};
[alert show];
BSAlertViewDelegateBlock.hとBSAlertViewDelegateBlock.mの実装はGitHubの上で利用可能ですが、私はここにコードを転載しました:
BSAlertViewDelegateBlock.h
#import <UIKit/UIKit.h>
/**
Adapts UIAlertViewDelegate protocol into a block-friendly interface.
*/
@interface BSAlertViewDelegateBlock : NSObject<UIAlertViewDelegate>
/**
Designated initializer.
*/
-(id) initWithAlertView:(UIAlertView*) alertView;
@property (nonatomic,strong) void(^clickedButtonAtIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex);
@property (nonatomic,strong) void(^alertViewCancelBlock)(UIAlertView* alertView);
@property (nonatomic,strong) void(^willPresentAlertViewBlock)(UIAlertView* alertView);
@property (nonatomic,strong) void(^didPresentAlertViewBlock)(UIAlertView* alertView);
@property (nonatomic,strong) void(^willDismissWithButtonIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex);
@property (nonatomic,strong) void(^didDismissWithButtonIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex);
@property (nonatomic,strong) BOOL(^alertViewShouldEnableFirstOtherButtonBlock)(UIAlertView* alertView);
@end
BSAlertViewDelegateBlock.m
#import <objc/runtime.h>
#import "BSAlertViewDelegateBlock.h"
const char* const BSAlertViewDelegateBlockKey = "BSAlertViewDelegateBlockKey";
@interface BSAlertViewDelegateBlock()
@property (nonatomic,weak) UIAlertView* alertView;
@end
@implementation BSAlertViewDelegateBlock
-(void) alertViewDelegateBlock_cleanup
{
UIAlertView* alertView = self.alertView;
// remove all handler blocks in case one of these blocks inadvertendly caused a circular reference to this delegate object.
self.clickedButtonAtIndexBlock = nil;
self.alertViewCancelBlock = nil;
self.willPresentAlertViewBlock = nil;
self.didPresentAlertViewBlock = nil;
self.willDismissWithButtonIndexBlock = nil;
self.didDismissWithButtonIndexBlock = nil;
self.alertViewShouldEnableFirstOtherButtonBlock = nil;
// finally remove this delegate from the alert view
if (alertView.delegate == self) {
alertView.delegate = nil;
objc_setAssociatedObject(alertView, BSAlertViewDelegateBlockKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
-(id) initWithAlertView:(UIAlertView *)alertView
{
if (self = [super init]) {
self.alertView = alertView;
objc_setAssociatedObject(alertView, BSAlertViewDelegateBlockKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
alertView.delegate = self;
}
return self;
}
#pragma mark UIAlertViewDelegate
// Called when a button is clicked. The view will be automatically dismissed after this call returns
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
void(^clickedButtonAtIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex) = self.clickedButtonAtIndexBlock;
if (clickedButtonAtIndexBlock) {
clickedButtonAtIndexBlock(alertView,buttonIndex);
}
}
// Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button.
// If not defined in the delegate, we simulate a click in the cancel button
- (void)alertViewCancel:(UIAlertView *)alertView
{
void(^alertViewCancelBlock)(UIAlertView* alertView) = self.alertViewCancelBlock;
if (alertViewCancelBlock) {
alertViewCancelBlock(alertView);
}
[self alertViewDelegateBlock_cleanup];
}
- (void)willPresentAlertView:(UIAlertView *)alertView
{
void(^willPresentAlertViewBlock)(UIAlertView* alertView) = self.willPresentAlertViewBlock;
if (willPresentAlertViewBlock) {
willPresentAlertViewBlock(alertView);
}
}
- (void)didPresentAlertView:(UIAlertView *)alertView
{
void(^didPresentAlertViewBlock)(UIAlertView* alertView) = self.didPresentAlertViewBlock;
if (didPresentAlertViewBlock) {
didPresentAlertViewBlock(alertView);
}
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
void(^willDismissWithButtonIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex) = self.willDismissWithButtonIndexBlock;
if (willDismissWithButtonIndexBlock) {
willDismissWithButtonIndexBlock(alertView,buttonIndex);
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
void(^didDismissWithButtonIndexBlock)(UIAlertView* alertView,NSInteger buttonIndex) = self.didDismissWithButtonIndexBlock;
if (didDismissWithButtonIndexBlock) {
didDismissWithButtonIndexBlock(alertView,buttonIndex);
}
[self alertViewDelegateBlock_cleanup];
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
BOOL(^alertViewShouldEnableFirstOtherButtonBlock)(UIAlertView* alertView) = self.alertViewShouldEnableFirstOtherButtonBlock;
if (alertViewShouldEnableFirstOtherButtonBlock) {
return alertViewShouldEnableFirstOtherButtonBlock(alertView);
}
// default to enable.
return YES;
}
@end
鮮やかな溶液。旗のために万歳!ありがとう。 – JoBu1324
うわー。あなたが帰ってくるとは決して想像もしませんでした。私の答えはとても遅かったです。それが助けてくれてうれしい。 :) –