美文网首页iOS常用
iOS 多弹窗顺序弹出

iOS 多弹窗顺序弹出

作者: MQ_Twist | 来源:发表于2020-08-29 17:31 被阅读0次

    明日安在,无人能允。

    前言

    弹出在交互上是个好东西,但是如果一个view有很多弹窗且产品要求按照一定的顺序弹出,emmm...很好,就很棒!

    先上需求

    目前有三个弹窗A -> B -> C(以后会不会加谁知道呢),现在弹窗要按在这个顺序来,每次只能弹一个,三个都是网络请求,不知道哪个结果先回来。分析一下,有如下场景:

    • 理想型
      数据顺序返回,顺序展示。期间通过弹窗跳转其他页面,返回后继续顺序展示。
    • 进阶型
      B数据先回,B显示ing时,A、C数据返回,不管谁数据先回来,B消失后都从A开始展示。期间通过弹窗跳转其他页面,返回后继续顺序展示。
    • 高端型
      A先回来,B是定时任务。通过A跳转到其他页面后B数据回来,正常情况下, 返回后会弹B。特别的,在其他页面某项操作后,B不用弹了,返回后B不弹。

    刺激!!!

    正题

    简单分析一下:

    • 1、标识一个弹窗要有三元素:弹窗类型、弹窗状态(参考线程生命周期)、弹窗展示用的数据。
      所以创建以下任务类:

    .h

    typedef NS_ENUM(NSInteger, MQRoomAlertTaskType) {
        MQRoomAlertTaskType_Runnable = 0,       //就绪
        MQRoomAlertTaskType_Running,            //执行中
        MQRoomAlertTaskType_end,                //完成
        
    };
    
    typedef NS_ENUM(NSInteger, MQRoomAlertType) {
        MQRoomAlertType_HongBao = 0,        //红包
        MQRoomAlertType_GrowGift,           //成长礼包
        MQRoomAlertType_Addention,          //关注
    };
    
    
    @interface MQRoomAlertOrderTask : NSObject
    
    /** 弹窗种类 */
    @property (nonatomic, assign) MQRoomAlertType alertType;
    @property (nonatomic, strong) id taskData;
    /** 任务状态 */
    @property (nonatomic, assign) MQRoomAlertTaskType taskType;
    
    
    @end
    
    • 2、 顺序展示,简单点用数组。有跨页面操作,用单例。创建以下管理类:

    .h

    @interface MQRoomAlertOrderManager : NSObject
    
    + (instancetype)shareInstance;
    
    //当前可执行任务
    @property (nonatomic, strong, readonly, nullable) MQRoomAlertOrderTask *curTask;
    /** 是否正在执行 */
    @property (nonatomic, assign, readonly) BOOL isExecuting;
    
    /** 缓存 */
    - (void)setTasKWithData:(id)data taskType:(MQRoomAlertType)alertType;
    /** 执行 */
    - (void)execute;
    /** 是否正在执行 */
    - (BOOL)executing;
    /** 完成 */
    - (void)complete;
    /** 清空 */
    - (void)clear;
    /** 根据任务类型获取任务 */
    - (MQRoomAlertOrderTask *)getTaskWithAlertType:(MQRoomAlertType)alertType;
    
    /** 销毁单例 */
    - (void)destroy;
    
    @end
    
    • 3、使用的时候采用递归方式
      核心代码
    - (void)orderAlert {
        MQRoomAlertOrderManager *manager = [MQRoomAlertOrderManager shareInstance];
        if (manager.isExecuting) {//正在执行任务,既有弹窗在显示
            return;
        }
        if (manager.curTask) {
            switch (manager.curTask.alertType) {
                case MQRoomAlertType_HongBao: {
                    NSLog(@">>>>>>MQRoomAlertType_HongBao");
                    //标记执行
                    [manager execute];
                    dispatch_async(self.queue, ^{
                        //模拟弹窗时间
                        sleep(arc4random() % 5 + 1);
                        //取当前任务数据
    //                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                        [self nextAlert];
                    });
                    break;
                }case MQRoomAlertType_GrowGift: {
                    NSLog(@">>>>>>MQRoomAlertType_GrowGift");
                    //标记执行
                    [manager execute];
                    dispatch_async(self.queue, ^{
                        //模拟弹窗时间
                        sleep(arc4random() % 5 + 1);
                        //取当前任务数据
    //                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                        [self nextAlert];
                    });
                    break;
                }case MQRoomAlertType_Addention: {
                    NSLog(@">>>>>>MQRoomAlertType_Addention");
                    //标记执行
                    [manager execute];
                    dispatch_async(self.queue, ^{
                        //模拟弹窗时间
                        sleep(arc4random() % 5 + 1);
                        //取当前任务数据
    //                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                        [self nextAlert];
                    });
                    break;
                }
                default:
                    break;
            }
        }else {
            self.hadTask = NO;
            NSLog(@">>>all task completed");
        }
    }
    
    - (void)nextAlert {
        //当前任务完成
        [[MQRoomAlertOrderManager shareInstance] complete];
        //递归执行下一任务
        [self orderAlert];
    }
    

    该管理类只是用来缓存弹窗数据、标记弹窗状态,不要把业务逻辑代码写到这里面来。

    注意

    若是那种跳转到其它页面后,改变某个任务的状态,这时候只需要获取对应task,然后把taskType设置为MQRoomAlertTaskType_end就可以了。

    //根据类型获取某一任务
    MQRoomAlertOrderTask *task = [[MQRoomAlertOrderManager shareInstance] getTaskWithAlertType:MQRoomAlertType_GrowGift];
    //改变任务状态
    task.taskType = MQRoomAlertTaskType_end;
    

    Demo地址 传送门

    后记

    逻辑比较复杂的,还是脑图好用,单在那想容易掉头发。

    相关文章

      网友评论

        本文标题:iOS 多弹窗顺序弹出

        本文链接:https://www.haomeiwen.com/subject/pghjsktx.html