從零開始設計搭建ios App框架(三)

為App添加消息提示框


所有的App都會有消息提示,如簡單的提示框、詢問框。此文不是介紹如何自定義消息提示框,消息提示使用ios自帶的UIAlertView、UIAlertController。
也許有人立即想到,這太簡單了,馬上寫給你看。

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:actionTitles, nil];
[alert show];

//回調
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    //事件處理
}

相信大家一個App里面消息提示肯定會有好多,難道在每個使用的地方加上如下代碼?這樣不覺得重復的代碼比較多嗎,我們常說代碼復用,是不是可以重新設計下,提升一下代碼復用性呢?當然是可以的。
在我看來,大多數的數據流轉,業務邏輯都會扯到ViewController,這樣就會使用Controller變胖,大神們都會了解MVC、MVP、MVVM設計模式,我理解不是很透,我也不多說什么了。我認為一個好的App框架的設計是要滿足功能模塊化,低偶合,代碼復用性強,調用方便簡潔,可擴展性就很不錯了。
哈哈,不扯遠了,入正題。只需要在ViewController擴展幾個方法。

/*
 消息提示,錯誤提示
 */
@interface PGBaseController (errorMsgView)

#pragma mark message
- (void)showMsg:(NSString *)szMsg;
- (void)showTitle:(NSString *)szTitle msg:(NSString *)szMsg;
- (void)showAskAlertTitle:(NSString *)title
                  message:(NSString *)message
                      tag:(NSInteger)tag
                   action:(void(^)(NSInteger alertTag, NSInteger actionIndex))block
        cancelActionTitle:(NSString *)cancelTitle
       otherActionsTitles:(NSString *)actionTitles,...;

@end

方法實現

#pragma mark message
- (void)showMsg:(NSString *)szMsg {
    [self showTitle:nil msg:szMsg];
}

- (void)showTitle:(NSString *)szTitle msg:(NSString *)szMsg {
    [self showAskAlertTitle:szTitle message:szMsg tag:0 action:nil cancelActionTitle:@"確定" otherActionsTitles:nil];
}

- (void)showAskAlertTitle:(NSString *)title
                  message:(NSString *)message
                      tag:(NSInteger)tag
                   action:(void(^)(NSInteger alertTag, NSInteger actionIndex))block
        cancelActionTitle:(NSString *)cancelTitle
       otherActionsTitles:(NSString *)actionTitles,... {
    
    NSMutableArray *arrayTitles = [[NSMutableArray alloc] init];
    [arrayTitles addObject:cancelTitle];
    
    NSString *szActionTitle = nil;
    va_list argumentList;
    if(actionTitles) {
        [arrayTitles addObject:actionTitles];
        va_start(argumentList, actionTitles);
        szActionTitle = va_arg(argumentList, NSString *);
        while(szActionTitle) {
            [arrayTitles addObject:szActionTitle];
            szActionTitle = va_arg(argumentList, NSString *);
        }
        
        va_end(argumentList);
    }
    
    if(IOS8_LATER) {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        for(NSInteger i = 0; i < arrayTitles.count; i++)
        {
            NSString *string = [arrayTitles objectAtIndex:i];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:string style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                if(block)
                {
                    block(tag, i);
                }
            }];
            [alertController addAction:okAction];
        }
        [self presentViewController:alertController animated:YES completion:nil];
    } else {
#if __IPHONE_OS_VERSION_MAX_ALLOWED <= __IPHONE_8_0
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:actionTitles, nil];
        alert.alertActionBlock = block;
        [alert show];
#endif
    }
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED <= __IPHONE_8_0
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(alertView.alertActionBlock)
    {
        alertView.alertActionBlock(alertView.tag, buttonIndex);
    }
}
#endif

仔細看代碼的同學會發現這句 alertView.alertActionBlock(alertView.tag, buttonIndex); 印象中UIAlertView沒有這么個東西!!!這是使用了…… 對,沒錯就是Catagory+runtime。

UIAlertView+action.h

#import <UIKit/UIKit.h>

typedef void(^PGAlertActionBlock)(NSInteger alertTag, NSInteger actionIndex);

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
@interface UIAlertView (action)

@property(nonatomic, copy)PGAlertActionBlock alertActionBlock;

@end

#endif

UIAlertView+action.m

#import "UIAlertView+action.h"
#import <objc/runtime.h>

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
//定義常量 必須是C語言字符串
static char *actionNameKey = "actionNameKey";
@implementation UIAlertView (action)

- (void)setAlertActionBlock:(PGAlertActionBlock)alertActionBlock
{
    objc_setAssociatedObject(self, actionNameKey, alertActionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (PGAlertActionBlock)alertActionBlock
{
    return objc_getAssociatedObject(self, actionNameKey);
}

@end

#endif

如何使用呢?只需在有需要顯示的地方調用下面的方法就可以實現相應的功能。

[self showMsg:@"消息內容"];
[self showAskAlertTitle:@"標題" message:@"提示的內容" tag:0 action:^(NSInteger alertTag, NSInteger actionIndex) {
        //事件響應
        if(actionIndex == 0) {
            
        } else if(actionIndex == 1) {
            
        }
    } cancelActionTitle:@"取消" otherActionsTitles:@"確定",nil];

到現在已經完成此模塊的設計,有沒有發現,這樣使用挺方便的!!呵呵!!寫的不好勿噴。

共同學習進步!

上一節:從零開始設計搭建ios App框架(二)
下一節:錯誤提示頁面

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容