iOS简单调用系统提示框(UIAlertController)

iOS9开始UIAlertView不被推荐使用,取而代之的是iOS8推出的UIAlertController
从它们的命名就能看得出一个是继承了UIView,一个是继承了UIViewController。不少小伙伴看到这个变动后当场就不开心了。以前的UIAlertView到处可以调用,并且宏定义起来调用也非常方便。

#define Alert(msg) \
[[[UIAlertView alloc] initWithTitle:@"" \
message:msg \
delegate:nil \
cancelButtonTitle:@"确定" \
otherButtonTitles:nil, nil] show]; \

可是现在的UIAlertController是需要通过presentViewController来弹窗的,所以必须要拿到Controller才能调用,这样很不方便。让我们来看看有没有好的方法来改造一下呢。

要不来点简单粗暴的吧~


首先最最关键的就是获取当前显示的ViewController,也是顶层的ViewController。

#pragma mark - Utils
- (UIViewController *)getCurrentViewController
{
    UIViewController *currentViewController = nil;
    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    if ([window subviews].count == 0) {
        return nil;
    }
    if (window.windowLevel != UIWindowLevelNormal) {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for(UIWindow * subWindow in windows)
        {
            if (subWindow.windowLevel == UIWindowLevelNormal) {
                window = subWindow;
                break;
            }
        }
    }
    UIView *frontView = [[window subviews] objectAtIndex:0];
    id nextResponder = [frontView nextResponder];
    
    if ([nextResponder isKindOfClass:[UIViewController class]]) {
        currentViewController = nextResponder;
    } else {
        currentViewController = window.rootViewController;
    }
    return currentViewController;
}

获取到当前的ViewController后,就可以配置UIAlertController进行跳转,方法命名模仿UIAlertView,并且用Block代替了UIAlertDelegate中的alertView:clickedButtonAtIndex:代理方法。

#pragma mark -- base method
/**
 *  提示框基础方法
 *
 *  @param title             标题
 *  @param message           消息
 *  @param cancelButtonTitle 取消按钮标题
 *  @param cancelCallBack    取消按钮回调
 *  @param otherCallBack     其他按钮回调
 *  @param otherButtonTitles 其他按钮
 */
- (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle cancelCallBack:(CancelCallBack)cancelCallBack otherCallBack:(OtherCallBack)otherCallBack otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION{
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0
    //初始化AlertController
    UIAlertController *alertViewController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    //定义va_list
    va_list argsList;
    //指向首地址
    va_start(argsList, otherButtonTitles);
    NSInteger index = 0;
    //遍历
    while (otherButtonTitles) {
        //过滤入参类型
        if (![otherButtonTitles isKindOfClass:[NSString class]]) {
            break;
        }
        //过滤空字符串
        if (![self isBlankString:otherButtonTitles]) {
            //添加提示框按钮动作
            UIAlertAction *alertAction = [UIAlertAction actionWithTitle:otherButtonTitles style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                if (otherCallBack) {
                    [alertViewController dismissViewControllerAnimated:YES completion:nil];
                    otherCallBack(index);
                }
            }];
            [alertViewController addAction:alertAction];
        }
        //指向下一个地址
        otherButtonTitles = va_arg(argsList, NSString *);
        index++;
    }
    va_end(argsList);
    
    //取消按钮
    if (![self isBlankString:cancelButtonTitle]) {
        UIAlertAction *alertAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            //点击过后关闭提示框
            if (cancelCallBack) {
                [alertViewController dismissViewControllerAnimated:YES completion:nil];
                //取消回调方法
                cancelCallBack();
            }
        }];
        [alertViewController addAction:alertAction];
    }
    //从当前控制器中模态弹出提示框
    [[self getCurrentViewController] presentViewController:alertViewController animated:YES completion:nil];
    
#else

    self.cancelCallBack = [cancelCallBack copy];
    self.otherCallBack = [otherCallBack copy];
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil];
    va_list argsList;
    va_start(argsList, otherButtonTitles);
    NSInteger index = 0;
    while (otherButtonTitles) {
        if (![self isBlankString:otherButtonTitles]) {
            [alertView addButtonWithTitle:otherButtonTitles];
        }
        otherButtonTitles = va_arg(argsList, NSString *);
        index++;
    }
    va_end(argsList);
    
    [alertView show];
}

常用的类方法以及对象方法也进行了浅层封装

+ (instancetype)alertView {
    return [[[self class] alloc] init];
}

#pragma mark - public method
#pragma mark -- class method
/**
 *  类方法  提示框(只显示消息)
 *
 *  @param message 消息
 */
+ (void)showMessage:(NSString *)message {
    [[[self class] alertView] showMessage:message];
}

/**
 *  类方法  提示框(只显示标题和消息)
 *
 *  @param title   标题
 *  @param message 消息
 */
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message {
    [[[self class] alertView] showAlertViewWithTitle:title message:message];
}

/**
 *  类方法  提示框(只显示标题和消息)
 *
 *  @param title   标题
 *  @param message 消息
 *  @param dismissCallBack 确定回调
 */
+ (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message dismissCallBack:(CancelCallBack)dismissCallBack {
    [[[self class] alertView] showAlertViewWithTitle:title message:message dismissCallBack:dismissCallBack];
}

#pragma mark -- object method
/**
 *  提示框(只显示消息)
 *
 *  @param message 消息
 */
- (void)showMessage:(NSString *)message {
    [self showAlertViewWithTitle:nil message:message];
}

/**
 *  提示框(只显示标题和消息)
 *
 *  @param title   标题
 *  @param message 消息
 */
- (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message {
    [self showAlertViewWithTitle:title message:message cancelButtonTitle:@"确定" cancelCallBack:nil otherCallBack:nil otherButtonTitles:nil];
}

/**
 *  提示框(只显示标题和消息)
 *
 *  @param title   标题
 *  @param message 消息
 *  @param dismissCallBack 确定回调
 */
- (void)showAlertViewWithTitle:(NSString *)title message:(NSString *)message dismissCallBack:(CancelCallBack)dismissCallBack {
    [self showAlertViewWithTitle:title message:message cancelButtonTitle:@"确定" cancelCallBack:dismissCallBack otherCallBack:nil otherButtonTitles:nil, nil];
}

至此,我们的目标也就达成了。我们可以用宏定义简单的调用系统提示框了

#define XXALERT(msg) [ALAlertView showMessage:msg];

注意事项:

  1. 若需要界面显示时,就出现弹窗,建议在ViewDidAppear中调用。
  2. 设备是iOS9及之后版本的,同时弹出多个窗口时只会显示第一个,建议在cancelCallBack中多次弹出。
  3. 多个按钮的入参列表otherButtonTitles的顺序与otherCallBack中的返回的下标是一一对应的,从0开始。

Demo地址:
https://github.com/alanshen0118/ALAlertView.git

若有问题,小编会及时更正,请大家多多指教。
若觉得对您有用,请点下方喜欢,多谢支持~

Thanks~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,029评论 4 62
  • “你们都是要刺杀秦王的吗?”小陆惊讶地问道,“看来这秦王树敌无数,想要刺杀他的人居然都结成了帮会!” “难...
    拥衾听雨待晚虹阅读 180评论 0 1
  • 1 林格和杨菲是很要好的朋友,他们初高中一直在一起,彼此之间有很多共同的朋友。大学毕业后回到他们老家A市,一起到一...
    风儿飞阅读 396评论 4 3
  • 孩子不仅是父母爱情的结晶,更是家庭幸福的纽带,当小生命呱呱坠地,父母家人的心都被其紧抓,但至阳之体,稍不留神就可能...
    阅读中医阅读 519评论 0 0