iOS开发笔记iOS常用

iOS弹框统一管理器

2020-07-03  本文已影响0人  iOS俱哥

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

实现的功能:
缺点:

头文件

@interface AlertManager : NSObject

+ (instancetype)shareManager;

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

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

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

- (void)alertDissMissWithType:(NSString *)type;

- (void)removeWithType:(NSString *)type;

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

@end

管理器添加弹框代码

- (void)alertShowWithType:(NSString *)type
                   config:(AlertConfig *)config
                     show:(nonnull Block)showBlock
                  dismiss:(nonnull Block)dismissBlock{
    
    //排查是否重复添加
    NSArray * keys = self.alertCache.allKeys;
    if ([keys containsObject:type]) {
        showBlock(NO,@"type标识重复");
        NSLog(@"type(%@)标识重复",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,@"本次被隐藏了啊");
               }
           }
    }
    
    showBlock(YES,@"");
}

弹框消失的代码

- (void)alertDissMissWithType:(NSString *)type{
    
    
    AlertConfig *config = [self.alertCache objectForKey:type];
    Block  dismissBlock = config.dismissBlock;
    dismissBlock(YES,@"");
    
    //延迟释放其他block
    ZJSemaphoreCreate
    ZJSemaphoreWait
    [self.alertCache removeObjectForKey:type];
    ZJSemaphoreSignal
    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(), ^{
                    
                    showBlock(YES,@"");
                });
                break;
            }
        }
    }
}

欢迎大家使用和体验啊!
代码地址:https://github.com/zhengju/iOSDemos/tree/master/SpringBox

上一篇下一篇

猜你喜欢

热点阅读