隨著業(yè)務(wù)的延展,APP中會(huì)出現(xiàn)各類如通知、營(yíng)銷、優(yōu)惠信息等等一系列的彈窗,且樣式各異,彈出時(shí)機(jī)及順序不定,前期如果未做系統(tǒng)性的規(guī)劃,到中期就會(huì)形成邏輯災(zāi)難。
我自己的項(xiàng)目中就出現(xiàn)了這樣的問題,在和產(chǎn)品經(jīng)理溝通后得知,后續(xù)此類彈窗只會(huì)越來越多。遂決定對(duì)彈窗做系統(tǒng)性規(guī)劃和重構(gòu),一勞永逸。
主體思路是參考了類似英雄聯(lián)盟和王者榮耀這兩個(gè)游戲剛啟動(dòng)時(shí)的彈窗邏輯:
前提:后臺(tái)有彈窗配置,每個(gè)彈窗有一個(gè)對(duì)應(yīng)id、優(yōu)先級(jí)、展示人群、拓展項(xiàng)。
客戶端請(qǐng)求彈窗列表接口后返回一個(gè)彈窗數(shù)組,首先展示第一個(gè)彈窗
第一個(gè)彈窗彈出后,如果點(diǎn)擊了關(guān)閉,使用彈窗id,調(diào)用一個(gè)finish接口后,則按順序展示第二個(gè)。
第一個(gè)彈窗彈出后,如果點(diǎn)擊了彈窗,同樣使用彈窗id,調(diào)用一個(gè)finish接口后,跳轉(zhuǎn)至對(duì)應(yīng)落地頁,在落地頁返回時(shí),二次調(diào)用彈窗列表接口,此時(shí)因第一個(gè)彈窗已被finish,所以在二次調(diào)用時(shí),第一個(gè)彈窗不會(huì)再返回。
后面即可重復(fù)執(zhí)行此類彈窗彈出邏輯。彈窗類型中可能會(huì)包含倒計(jì)時(shí)自動(dòng)關(guān)閉等,可在倒計(jì)時(shí)結(jié)束時(shí)自動(dòng)調(diào)用finish,然后按順序彈出第二個(gè)彈窗。
UI層面可根據(jù)業(yè)務(wù)需求封裝兩到三類通用型彈窗,可改變文案、圖片、是否自動(dòng)關(guān)閉的相關(guān)屬性。
重點(diǎn)說明升級(jí)彈窗,如果是配置了強(qiáng)更,那升級(jí)彈窗即無法關(guān)閉,始終常駐,除非點(diǎn)擊了彈窗,會(huì)跳轉(zhuǎn)至市場(chǎng)進(jìn)行升級(jí),升級(jí)之后app會(huì)重新啟動(dòng),判斷版本已經(jīng)是最新后,升級(jí)彈窗則不再?gòu)棾觥?/p>
使用單例創(chuàng)建一個(gè)彈窗主體管理器,在管理器內(nèi)部添加上述邏輯。
管理器h文件:
@interface WindowPopManager : NSObject
+ (WindowPopManager*)shared;
-(void)showWindowPopWithPopArray:(NSMutableArray *)popArray;
@property (nonatomic, assign) BOOL popWindowIsShowing;//當(dāng)前彈窗是否正在展示
@property (nonatomic, strong) UIView *currentWindowPopView;//當(dāng)前正在展示額彈窗view
@end
管理器m文件:
單例創(chuàng)建管理器:
+ (WindowPopManager*)shared{
? ? static dispatch_once_t once;
? ? static WindowPopManager *shared;
? ? dispatch_once(&once, ^ {
? ? ? ? shared = [[WindowPopManageralloc]init];
? ? });
? ? returnshared;
}
調(diào)用彈出方法(此處以升級(jí)升級(jí)彈窗為例):
-(void)showWindowPopWithPopArray:(NSMutableArray *)popArray{
? ? if(self.popWindowIsShowing){
? ? ? ? return;
? ? }
? ? self.popArray= popArray;
? ? if(self.popArray.count){
? ? ? ? self.popWindowIsShowing = YES;
? ? ? ? NSDictionary*dict =self.popArray[0];
? ? ? ? NSString*type = dict[@"type"];
? ? ? ? if([typeisEqualToString:@"appupgrade"]){
? ? ? ? ? ? //===========================升級(jí)彈窗===========================
? ? ? ? ? ? self.updataView.descTextView.text= [NSStringstringWithFormat:@"%@", dict[@"data"][@"description"]];
? ? ? ? ? ? if([dict[@"data"][@"forceUpdate"]intValue] ==1) {
? ? ? ? ? ? ? ? self.updataView.closeButton.hidden=YES;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? self.updataView.closeButton.hidden=NO;
? ? ? ? ? ? }
? ? ? ? ? ? [KEY_WINDOWaddSubview:self.updataView];
? ? ? ? ? ? self.currentWindowPopView = self.updataView;
? ? ? ? }
}
彈窗finish方法(注:強(qiáng)更升級(jí)彈窗不調(diào)用該方法):
#pragma mark- 標(biāo)記消除彈框
-(void)windowFinishWithView:(UIView *)view{
? ? self.currentWindowPopView = nil;
? ? self.popWindowIsShowing = NO;
? ? if(self.popArray.count){
? ? ? ? NSDictionary*dict =self.popArray[0];
? ? ? ? [BTHTTPRequest windowFinishWithType:dict[@"type"] popId:dict[@"id"] Success:^(id? _Nonnull response) {
? ? ? ? ? ? if([response[@"code"]integerValue] ==200){
? ? ? ? ? ? }else{
? ? ? ? ? ? }
? ? ? ? }BTFail:^(NSError*_Nonnullerror) {
? ? ? ? }];
? ? }
}
最后:只是提供一個(gè)彈窗管理調(diào)度思路和大概的參考,因各類APP的業(yè)務(wù)繁雜,無法進(jìn)行完整的封裝,希望對(duì)你有幫助。