iOS弹框统一管理器

由于多个业务需要,在一个界面会有多个弹框的存在,而这多个弹框需要按顺序、优先级给统一管理起来,不然会杂乱无章的弹出,用户会一脸懵逼啊。
我写了一个管理器,把弹框的出现和消失给管理起来,出现和消失的时机给管理起来。
AlertManager不关心怎么显示和消失,也就是不关系的UI层面,只管理显示和消失两个block事件。

实现的功能:
  • 统一管理弹框
  • 弹框叠加显现
  • 弹框依次显现
  • 弹框的优先级排序
  • 弹框被拦截缓存起来;允许激活会在别的弹框消失后显示

头文件

@interface AlertManager : NSObject

+ (instancetype)shareManager;

/// 是否根据优先级排序 默认YES
@property (nonatomic,assign,readonly) BOOL isSortByPriority;

///被遮挡后的弹框先隐藏 默认是YES显示
@property (nonatomic,assign,readonly) BOOL isDisplayAfterCover;

/// 弹框展示
/// @param config 配置
/// @param showBlock 显示回调
/// @param dismissBlock 隐藏回调
- (void)alertShowWithConfig:(AlertConfig *)config show:(Block)showBlock dismiss:(Block)dismissBlock;

/// 清除弹框
- (void)alertDissMiss;

/// 清楚缓存
- (void)clearCache;

@end

管理器添加弹框代码

- (void)alertShowWithConfig:(AlertConfig *)config
                     show:(nonnull Block)showBlock
                  dismiss:(nonnull Block)dismissBlock{
    
    NSString *type = [NSString stringWithFormat:@"type%ld",(long)self.num];//累加的type
    self.num++;
    //排查是否重复添加
    NSArray * keys = self.alertCache.allKeys;
    if ([keys containsObject:type]) {
        showBlock(NO,@"type标识重复");
        return;
    }
    
    //重置优先级
    if (config.priority != AlertPriority1 && config.priority != AlertPriority2 && config.priority != AlertPriority3) {
        config.priority = AlertPriority1;
    }
    
    config.alertType = type;
    config.showBlock = showBlock;
    config.dismissBlock = dismissBlock;
    config.isDisplay = YES;//设置为当前显示
    //加入缓存
    ZJSemaphoreCreate
    ZJSemaphoreWait
    [self.alertCache setObject:config forKey:type];
    ZJSemaphoreSignal
    if (config.isIntercept && self.alertCache.allKeys.count > 1) {//self.alertCache.allKeys.count > 1 表示当前有弹框在显示
        
        //在此移除被拦截并且不被激活的弹框
        if (!config.isActivate) {
            ZJSemaphoreCreate
            ZJSemaphoreWait
            [self.alertCache removeObjectForKey:type];
            ZJSemaphoreSignal
        }
        config.isDisplay = NO;//重置为当前隐藏
        return;
    }
    
    //隐藏已经显示的弹框
    if (!self.isDisplayAfterCover) {
        NSArray * allKeys = [self.alertCache allKeys];
           for (NSString *key in allKeys) {
               AlertConfig *alertConfig = [self.alertCache objectForKey:key];
               if (alertConfig.isDisplay&&alertConfig.dismissBlock&&alertConfig!=config) {
                   alertConfig.isDisplay = NO;
                   alertConfig.dismissBlock(YES,@"本次被隐藏了啊");
               }
           }
    }
    ZJSemaphoreCreate1
    ZJSemaphoreWait1
    [self.currentDisplayAlerts addObject:config];
    ZJSemaphoreSignal1
    showBlock(YES,@"");
}

弹框消失的代码

- (void)alertDissMiss{
    
    //查找当前最上边的弹框
    
    AlertConfig *alertConfig = [self findAlertCurrentDisplay];

    if (alertConfig) {
        Block  dismissBlock = alertConfig.dismissBlock;
        dismissBlock(YES,@"");
        //延迟释放其他block
        ZJSemaphoreCreate
        ZJSemaphoreWait
        [self.alertCache removeObjectForKey:alertConfig.alertType];
        ZJSemaphoreSignal
        
        ZJSemaphoreCreate1
        ZJSemaphoreWait1
        [self.currentDisplayAlerts removeLastObject];
        ZJSemaphoreSignal1
    }

    NSArray * values = self.alertCache.allValues;
    
    //判断当前是否有显示-有,不显示弹框拦截的弹框
    if ([self displayAlert]) {
        return;
    }
    if (self.isSortByPriority) {
        values = [self sortByPriority:values];
    }
    //接下来是要显示被拦截的弹框
    if (values.count > 0) {

        //查找是否有可以显示的弹框 条件:1.已加入缓存 2.被拦截 3.可以激活显示
        //目前是从先加入的找起->优先级
        
        for (AlertConfig * config in values) {

            Block showBlock = config.showBlock;
            
            if (config.isIntercept && config.isActivate && showBlock) {
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    config.isDisplay = YES;
                    ZJSemaphoreCreate1
                    ZJSemaphoreWait1
                    [self.currentDisplayAlerts addObject:config];
                    ZJSemaphoreSignal1
                    showBlock(YES,@"");
                });
                break;
            }
        }
    }
}

具体使用

- (void)showAlertViewB {
    
    AlertConfig * config = [[AlertConfig alloc]initWithPatams:@{} activate:YES];
    config.priority = AlertPriority3;
    __weak typeof(self) weakSelf = self;
    [self.manager alertShowWithConfig:config show:^(BOOL isSuccess, NSString * _Nonnull message) {
        if (isSuccess) {
             __strong typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.alertViewB.hidden = NO;
        }
    } dismiss:^(BOOL isSuccess, NSString * _Nonnull message) {
         __strong typeof(weakSelf) strongSelf = weakSelf;

        strongSelf.alertViewB.hidden = YES;
    }];

}

- (void)hiddenAlertViewB {
    
    [self.manager alertDissMiss];
}

既然是弹框的统一管理,将要显示的弹框一定要加载管理器内来显示和移除才能起到作用。让管理器来管理弹框的显示和消失。

代码地址:https://github.com/zhengju/iOSDemos/tree/master/SpringBox

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