LoginSignup
4
4

More than 5 years have passed since last update.

iOS7のためのUIAlertViewのサポートが面倒なんですが・・・

Last updated at Posted at 2015-07-18

まだ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;
    }
}

実際のコードから余計な部分を剥がして書きましたので、実動作上は何らかの問題がでるかもしれません。
以上です。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4