[iOS] シンプルに統一したアラートを書けるライブラリ、RMUniversalAlertについて

2016.02.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

RMUniversalAlertとは、UIAlertViewUIActionSheet及び、UIAlertControllerのラッパークラスです。

iOS8で、UIAlertViewdeprecatedとなり、UIAlertControllerへの移行となりましたが、iOS7にも対応となると、OSに応じて使い分ける必要があります。

そして、この場合、ボタンを押した際の処理も、UIAlertView(iOS7以前)では、DelegateUIAlertController(iOS8以降)ならBlocksと違うため、煩雑になることは避けられません。

この問題に、シンプルに対応できるのが、RMUniversalAlertです。

RMUniversalAlertでは、OSのバージョンによって、内部でUIAlertViewUIActionContrllerを使い分け、ボタン押下時の処理もBlocksで統一されています。

独自のビューを作るのではなく、純正であるUIAlertView及びUIAlertControllerが使用されているため違和感もありません。

RMUniversalAlertは、MITライセンスで公開されており、CocoaPodで簡単にインストールが可能です。

pod 'RMUniversalAlert'

CocoaPodsによる、外部ライブラリの利用と作成

なお、2016年2月現在の最新バージョンは0.3です。

ライブラリの導入後は、下記のインポートで利用可能になります。

#import "RMUniversalAlert.h"

2 2種類のアラート

RMUniversalAlertでは、次の2種類のアラートが使用可能です。

  • Alert Views
  • Action Sheets

一つ目のAlert Viewsは、先に取り上げた、UIAlertView/UIAlertControllerのラッパーです。

そして、2つ目のAction Sheetsは、UIActionSheetのラッパーです。

どちらも、Blocksで統一したインターフェースを提供しています。

3 Alert Views

Alert Viewsのインターフェースは、次のとおりです。

+ (instancetype)showAlertInViewController:(UIViewController *)viewController
                                withTitle:(NSString *)title
                                  message:(NSString *)message
                        cancelButtonTitle:(NSString *)cancelButtonTitle
                   destructiveButtonTitle:(NSString *)destructiveButtonTitle
                        otherButtonTitles:(NSArray *)otherButtonTitles
                                 tapBlock:(RMUniversalAlertCompletionBlock)tapBlock;

実際に使って見ると、こんな感じになります。 このコードは、iOSのバージョンを意識することなく使用できます。

- (IBAction)tapShowAlertInViewControllerButton:(UIButton *)sender {
    [RMUniversalAlert showAlertInViewController:self
                                      withTitle:@"Title"
                                        message:@"Message"
                              cancelButtonTitle:@"Cancel"
                         destructiveButtonTitle:nil
                              otherButtonTitles:@[@"Button1",@"Button2"]
                                       tapBlock:^(RMUniversalAlert *alert, NSInteger buttonIndex){
                                           if (buttonIndex == alert.cancelButtonIndex) {
                                               NSLog(@"Cancel");
                                           } else if (buttonIndex >= alert.firstOtherButtonIndex) {
                                               NSLog(@"Button%ld",
                                                     (long)buttonIndex - alert.firstOtherButtonIndex);
                                           }
                                       }];

}

実行画面です。

001

4 Action Sheets

Action Sheetsのインターフェースは、次のとおりです。

+ (instancetype)showActionSheetInViewController:(UIViewController *)viewController
                                      withTitle:(NSString *)title
                                        message:(NSString *)message
                              cancelButtonTitle:(NSString *)cancelButtonTitle
                         destructiveButtonTitle:(NSString *)destructiveButtonTitle
                              otherButtonTitles:(NSArray *)otherButtonTitles
             popoverPresentationControllerBlock:(void(^)(RMPopoverPresentationController *popover))popoverPresentationControllerBlock
                                       tapBlock:(RMUniversalAlertCompletionBlock)tapBlock;

そして、実際に使って見ると、こんな感じになります。

- (IBAction)tapShowActionSheetInViewController:(UIButton *)sender {
    [RMUniversalAlert showActionSheetInViewController:self
                                            withTitle:@"Title"
                                              message:@"Message"
                                    cancelButtonTitle:@"Cancel"
                               destructiveButtonTitle:@"Delete"
                                    otherButtonTitles:@[@"Button", @"Button2"]
                   popoverPresentationControllerBlock:^(RMPopoverPresentationController *popover){
                       popover.sourceView = self.view;
                       popover.sourceRect = sender.frame;
                   }
                                             tapBlock:^(RMUniversalAlert *alert, NSInteger buttonIndex){
                                                 if (buttonIndex == alert.cancelButtonIndex) {
                                                     NSLog(@"Cancel");
                                                 } else if (buttonIndex == alert.destructiveButtonIndex) {
                                                     NSLog(@"Delete");
                                                 } else if (buttonIndex >= alert.firstOtherButtonIndex) {
                                                     NSLog(@"Button%ld", (long)buttonIndex - alert.firstOtherButtonIndex);
                                                 }
                                             }];
}

実行画面です。

002

5 最後に

RMUniversalAlertを使用すると、アラートに関する処理を全てBlacksで、統一した書き方ができるため、非情に使いやすいのでは、と感じました。

6 参考資料


https://github.com/ryanmaxwell/RMUniversalAlert
http://cocoadocs.org/docsets/RMUniversalAlert/0.3/