iOS常用

iOS 多弹窗顺序弹出

2020-08-29  本文已影响0人  MQ_Twist

明日安在,无人能允。

前言

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

先上需求

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


刺激!!!

正题

简单分析一下:

.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

.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
- (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地址 传送门

后记

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

上一篇下一篇

猜你喜欢

热点阅读