近來因爲App中彈窗過多,再加上還有半透明的引導層,時常會出現多個彈窗重疊彈出,甚至會伴隨引導層一塊兒彈出,極大的影響了用戶體驗。git
上述問題,其實很簡單,只須要添加一個彈窗隊列便可。github
可是與此同時咱們又添加了新的需求以下:數據庫
因爲項目中咱們採用了模塊化的方式精簡代碼、下降工做耦合,因此咱們的彈窗並非基於ViewController彈出的,而是在須要彈出的時候獲取當前顯示的ViewController用於顯示的。數組
例如項目中任務模塊,任務是能夠在任何地方任什麼時候候被完成,任務自己不關心它是位於什麼時候何地被完成,只須要關心完成後,須要對應作出什麼操做,例如寫本地數據庫,更新用戶數據,彈出完成任務提示,和ViewController並沒有大的關聯。bash
簡單的說,咱們的彈窗是屬於功能塊的,而功能塊不該該且不用去關心當前展現的ViewController是哪個。架構
本文介紹的一個彈窗架構實際也能夠歸類爲一個彈窗功能模塊,當彈窗出如今不應出現的地方時,它來負責調度和處理,其過程對於其它功能模塊透明,並不產生任何耦合度。其實現功能以下:app
WKViewManager 彈窗隊列管理類,使用AOP切片基於self-manager模式封裝,高內聚性,幾乎不會和ViewController或功能模塊產生耦合。ide
因爲是彈窗視圖的一個管理工具,全部須要被管理的彈窗均需屬於WKBaseView的子類,項目中已書寫對應所須要的彈窗基類如WKPopBaseView、WKStepMaskGuideView等等,有須要構建彈窗的時候能夠去查看相關類。模塊化
(關於WKBaseView,是一個封裝的很是完善的彈窗基類,預計後續會寫一篇文章詳細介紹,它的整個結構是很是完善,針對彈窗功能幾乎沒有擴充瓶頸)工具
白名單模式只有一個關鍵內容
白名單字典 - whiteList
複製代碼
白名單字典位於WKViewManager類中。
字典中key爲從屬於WKBaseView的子類的類名字符串,value是一個數組,裏面放入對應的ViewController的類名字符串。
例如 白名單內容爲
@{@"KMAnnouncementView":@[@"HJTMainTabBarVC"]};
複製代碼
則在廣告公告模塊中,KMAnnouncementView調用顯示時,所獲取的View不是HJTMainTabBarVC的View,則KMAnnouncementView會進入白名單待顯示數組中,當HJTMainTabBarVC調用viewwillappear時纔會實際被顯示出來。
白名單中的key對應的view永遠只會出如今其對應的value中的vc上,即使你在其餘任何VC上調用顯示顯示KMAnnouncementView, KMAnnouncementView也只會出如今其對應的value的vc上。
黑名單模式包括兩個關鍵內容。
黑名單字典 - blackList
黑名單HomeVC - blackListHomeVCClassName
複製代碼
黑名單字典位於WKViewManager類中。
字典中key爲ViewController的類名字符串,value是一個數組,裏面應放入對應的從屬於WKBaseView的子類的類名字符串。
例如 黑名單內容爲
@{@"KMBaseViewController",@[@"WKPopBaseView"]};
複製代碼
則代表,WKPopBaseView類(不包含其子類),若是因爲功能塊解耦或者其它緣由,致使WKPopBaseView被展現於KMBaseViewController(不包含其子類)的子視圖上時,WKViewManager會攔截此行爲,將WKPopBaseView實例存入黑名單待顯示數組,當回到黑名單HomeVC時再顯示出來。從而實現了WKPopBaseView必定不會出如今KMBaseViewController的視圖上。
黑名單中key對應的vc顯示時,其對應的value中的view必然不會出現,若是被強制出現時,其也不會出現,直到黑名單homeVC的viewwillappear被調用纔會顯示。
因爲隊列基於viewcontroller的,因此很簡單隻須要hook viewcontroller的 willappear和diddisappear便可,在willappear裏面找到隊列設置suspended爲NO,在diddisappear裏面suspended爲yes便可
####Demo地址
前提:由於內部實現使用了Masonry佈局,因此須要先Pod Masonry三方庫。
下載Demo,找到BaseView文件夾拖入項目。
將文件中的WKViewManagerHeader.h文件加入全局頭文件.pch中。
新建的View繼承自WKPopBaseView,並重寫setInterFace,需首先調用父類的實現
- (void)setInterFace
{
[super setInterFace];
//TODO contentview的高度必須設置
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.centerY.equalTo(self).offset(SCREEN_HEIGHT);
make.width.height.equalTo(@200);
}];
}
複製代碼
可自定義出現和消失動畫--------實現updateContentViewConstraint:(BOOL)isShow方法
- (void)updateContentViewConstraint:(BOOL)isShow
{
[self.contentView mas_updateConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self).offset(isShow ? 0 : SCREEN_HEIGHT);
}];
}
複製代碼
還有更多可自定義的效果,可經過頂層基類WKbaseVIew封裝的聲明週期實現。詳情請查看Demo
初始化後,在須要展現的地方調用showInView:isShow:方法便可。
WKTestView * v = [[WKTestView alloc] init];
v.title = @"This is Test View can not show in HomePage";
[v showInView:self.view isShow:YES];
複製代碼
郵箱357863248@qq.com