iOS 多彈窗順序彈出

明日安在,無人能允。

前言

彈窗在交互上是個好東西,但是如果一個view有很多彈窗且產(chǎn)品要求按照一定的順序彈出,emmm...很好,就很棒!

先上需求

目前有三個彈窗A、B、C(以后會不會加誰知道呢),現(xiàn)在彈窗要按照A -> B -> C這個順序來,每次只能彈一個,三個都是網(wǎng)絡請求,不知道哪個結(jié)果先回來。分析一下,有如下場景:

  • 理想型
    數(shù)據(jù)順序返回,順序展示。期間通過彈窗跳轉(zhuǎn)其他頁面,返回后繼續(xù)順序展示。
  • 進階型
    B數(shù)據(jù)先回,B顯示ing時,A、C數(shù)據(jù)返回,緩存數(shù)據(jù)。不管誰數(shù)據(jù)先回來,B消失后都從A開始展示。期間通過彈窗跳轉(zhuǎn)其他頁面,返回后繼續(xù)順序展示。
  • 高端型
    A先回來,B是定時任務。通過A跳轉(zhuǎn)到其他頁面后B數(shù)據(jù)回來,正常情況下, 返回后會彈B。特別的,在其他頁面某項操作后,B不用彈了,返回后B不彈。

刺激?。?!

正題

簡單分析一下:

  • 1、標識一個彈窗要有三元素:彈窗類型、彈窗狀態(tài)(參考線程生命周期)、彈窗展示用的數(shù)據(jù)。
    所以創(chuàng)建以下任務類:

.h

typedef NS_ENUM(NSInteger, MQRoomAlertTaskType) {
    MQRoomAlertTaskType_Runnable = 0,       //就緒
    MQRoomAlertTaskType_Running,            //執(zhí)行中
    MQRoomAlertTaskType_end,                //完成
    
};

typedef NS_ENUM(NSInteger, MQRoomAlertType) {
    MQRoomAlertType_HongBao = 0,        //紅包
    MQRoomAlertType_GrowGift,           //成長禮包
    MQRoomAlertType_Addention,          //關(guān)注
};


@interface MQRoomAlertOrderTask : NSObject

/** 彈窗種類 */
@property (nonatomic, assign) MQRoomAlertType alertType;
@property (nonatomic, strong) id taskData;
/** 任務狀態(tài) */
@property (nonatomic, assign) MQRoomAlertTaskType taskType;


@end
  • 2、 順序展示,簡單點用數(shù)組。有跨頁面操作,用單例。創(chuàng)建以下管理類:

.h

@interface MQRoomAlertOrderManager : NSObject

+ (instancetype)shareInstance;

//當前可執(zhí)行任務
@property (nonatomic, strong, readonly, nullable) MQRoomAlertOrderTask *curTask;
/** 是否正在執(zhí)行 */
@property (nonatomic, assign, readonly) BOOL isExecuting;

/** 緩存 */
- (void)setTasKWithData:(id)data taskType:(MQRoomAlertType)alertType;
/** 執(zhí)行 */
- (void)execute;
/** 是否正在執(zhí)行 */
- (BOOL)executing;
/** 完成 */
- (void)complete;
/** 清空 */
- (void)clear;
/** 根據(jù)任務類型獲取任務 */
- (MQRoomAlertOrderTask *)getTaskWithAlertType:(MQRoomAlertType)alertType;

/** 銷毀單例 */
- (void)destroy;

@end
  • 3、使用的時候采用遞歸方式
    核心代碼
- (void)orderAlert {
    MQRoomAlertOrderManager *manager = [MQRoomAlertOrderManager shareInstance];
    if (manager.isExecuting) {//正在執(zhí)行任務,既有彈窗在顯示
        return;
    }
    if (manager.curTask) {
        switch (manager.curTask.alertType) {
            case MQRoomAlertType_HongBao: {
                NSLog(@">>>>>>MQRoomAlertType_HongBao");
                //標記執(zhí)行
                [manager execute];
                dispatch_async(self.queue, ^{
                    //模擬彈窗時間
                    sleep(arc4random() % 5 + 1);
                    //取當前任務數(shù)據(jù)
//                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                    [self nextAlert];
                });
                break;
            }case MQRoomAlertType_GrowGift: {
                NSLog(@">>>>>>MQRoomAlertType_GrowGift");
                //標記執(zhí)行
                [manager execute];
                dispatch_async(self.queue, ^{
                    //模擬彈窗時間
                    sleep(arc4random() % 5 + 1);
                    //取當前任務數(shù)據(jù)
//                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                    [self nextAlert];
                });
                break;
            }case MQRoomAlertType_Addention: {
                NSLog(@">>>>>>MQRoomAlertType_Addention");
                //標記執(zhí)行
                [manager execute];
                dispatch_async(self.queue, ^{
                    //模擬彈窗時間
                    sleep(arc4random() % 5 + 1);
                    //取當前任務數(shù)據(jù)
//                    id data = [MQRoomAlertOrderManager shareInstance].curTask.taskData;
                    [self nextAlert];
                });
                break;
            }
            default:
                break;
        }
    }else {
        self.hadTask = NO;
        NSLog(@">>>all task completed");
    }
}

- (void)nextAlert {
    //當前任務完成
    [[MQRoomAlertOrderManager shareInstance] complete];
    //遞歸執(zhí)行下一任務
    [self orderAlert];
}

該管理類只是用來緩存彈窗數(shù)據(jù)、標記彈窗狀態(tài),不要把業(yè)務邏輯代碼寫到這里面來。

注意

若是那種跳轉(zhuǎn)到其它頁面后,改變某個任務的狀態(tài),這時候只需要獲取對應task,然后把taskType設置為MQRoomAlertTaskType_end就可以了。

//根據(jù)類型獲取某一任務
MQRoomAlertOrderTask *task = [[MQRoomAlertOrderManager shareInstance] getTaskWithAlertType:MQRoomAlertType_GrowGift];
//改變?nèi)蝿諣顟B(tài)
task.taskType = MQRoomAlertTaskType_end;

Demo地址 傳送門

后記

邏輯比較復雜的,還是思維導圖好用,單在那想容易掉頭發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容