まだiOS7のサポートも続けることがあると思いますが、UIAlertViewが面倒くさいのでブロック記述を使ったiOS8以降と互換なクラスを作って見ました。
ブロック関数を使った実装は同期部分などの難しいところもありますが、慣れてくるとdelegateを使いたくなくなります。
そこでiOS7の対応も含めて、delegateを排除することにしました。ユーティリティクラスの内部にdelegate処理部分を隠蔽して、クラスを使う側はブロック関数で動作させます。
さらに簡単に使うためにシングルトンの実装にしてアラートの多重呼び出し問題を回避?することもできると思います。
まずは、宣言部分から。
objective-c
typedef enum CommonIntaractiveDefine_t
{
CommonIntaractiveDefine_None = -1,
CommonIntaractiveDefine_Cancel = 0,
CommonIntaractiveDefine_OK
}
CommonIntaractiveDefine;
@interface AlertUtils : NSObject
{
// iOS7アラート用
UIAlertView * mAlertView;
// iOS7アラート用のブロック関数・変数
void (^mShowHideFunction)(BOOL, NSInteger);
}
@property (nonatomic, assign, readonly) BOOL busy;
@end
続いて、iOS7用とiOS8以降のアラート実装部分です。
objective-c
/**
* OK、キャンセルボタン付きアラートダイアログを表示する
*
* @param viewController 親のviewController
* @param title タイトル
* @param msg メッセージ
* @param cbBlock ブロック関数
*/
-(void)alert:(UIViewController *)viewController
title:(NSString *)title
message:(NSString *)msg
ok:(NSString *)ok
cancel:(NSString *)cancel
cbBlock:(void (^)(BOOL appeared, NSInteger pushedIndex))cbBlock
{
NSString * osVersion = [[UIDevice currentDevice] systemVersion];
float fOsVersion = [osVersion floatValue];
if(fOsVersion >= 8.0)
{
// ====== iOS8用 ======
__block UIViewController * vc = viewController;
//[vc retain];
UIAlertController * alertController =
[UIAlertController alertControllerWithTitle:title message:msg
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction
actionWithTitle:ok
style:UIAlertActionStyleDefault
handler:^( UIAlertAction * action)
{
if(cbBlock!=nil)
{
cbBlock(FALSE,CommonIntaractiveDefine_OK);
}
_busy = FALSE;
//[vc release];
vc = nil;
}]];
[alertController addAction:[UIAlertAction
actionWithTitle:cancel
style:UIAlertActionStyleDefault
handler:^( UIAlertAction * action)
{
if(cbBlock!=nil)
{
cbBlock(FALSE,CommonIntaractiveDefine_Cancel);
}
_busy = FALSE;
//[vc release];
vc = nil;
}]];
[vc presentViewController:alertController animated:YES completion:^{
_busy = TRUE;
if(cbBlock!=nil)
{
cbBlock(TRUE,CommonIntaractiveDefine_None);
}
}];
}
else
{
// ====== iOS7用 ======
if(mAlertView==nil)
{
mShowHideFunction = cbBlock;
mAlertView = [[UIAlertView alloc]
initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:cancel
otherButtonTitles:ok, nil];
[mAlertView show];
//[mAlertView release];
mAlertView = nil;
}
}
}
UIAlertViewのdelegateを書きます。
objective-c
- (void)willPresentAlertView:(UIAlertView *)alertView
{
_busy = TRUE;
if(mShowHideFunction!=nil)
{
mShowHideFunction(TRUE,CommonIntaractiveDefine_None);
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(mShowHideFunction!=nil)
{
mShowHideFunction(FALSE,buttonIndex);
}
_busy = FALSE;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView == mAlertView)
{
if(mShowHideFunction!=nil)
{
mShowHideFunction(FALSE,buttonIndex);
}
mAlertView = nil;
}
}
- (void)alertViewCancel:(UIAlertView *)alertView
{
if(alertView == mAlertView)
{
if(mShowHideFunction!=nil)
{
mShowHideFunction(FALSE,CommonIntaractiveDefine_Cancel);
}
mAlertView = nil;
}
}
実際のコードから余計な部分を剥がして書きましたので、実動作上は何らかの問題がでるかもしれません。
以上です。