移動應用的開發中,有時咱們會須要例如更換皮膚此類的功能,andorid採用xml配置UI的方式,這個問題或許還容易解決些,iOS的主要UI邏輯則是在代碼中控制的,若是沒有一個強大的框架方案,這個問題將變得很是棘手。網上也有不少諸如此類功能的優秀案例與框架,在這篇博客中,我與你們分享下個人解決方案,其中若是有不恰或者糟糕之處,但願與高人一塊兒交流。框架
首先個人設計思路是採用通知的方式,原理能夠以下理解爲如下幾步:post
一、在系統的通知中心註冊一個通知優化
二、全部須要更改皮膚功能的controller做爲這個通知的監聽者ui
三、設計一個皮膚的model類spa
四、將controller中有關皮膚設置的屬性從model中取設計
五、在切換皮膚前更改皮膚modelcode
六、發送更改皮膚的通知orm
上面的6個步驟是這整個框架的基本邏輯,框架無非是將這些邏輯進行優化與封裝。下面這張圖很爛,可是思路很清晰:server
首先最上面是我設計的一個切換主題的manager,我這裏的設計有個缺陷,我將manager和主題配置相關的model混合在了一塊兒,寫的時候簡單了些,可這給框架的邏輯上帶來了混亂,因此我在圖中使用曲線和虛橢圓將其分離,manager來控制切換model的屬性,咱們在controller中取model的屬性進行配置,這個manager的邏輯位置是交互時間與通知中心的橋樑。manager中的核心代碼以下:xml
//單例方法 +(instancetype)sharedTheSingletion{ static YHTopicColorManager * sharedModel = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedModel = [[YHTopicColorManager alloc] init]; }); return sharedModel; } //這個方法應該分離在model中,從本地讀取當前的主題模式,更改後咱們只須要更改本地數據 而後從新調用這個方法便可 -(void)getTopicModel{ //從本地讀取 int tp = [YHSASystemSettingManager sharedTheSingletion].topic; if (tp==0) { //默認爲白天主題 tp=dayTime; [YHSASystemSettingManager sharedTheSingletion].topic = tp; } switch (tp) { //這裏是我定義的一些枚舉,拿白天和夜間模式示範 case dayTime://白天模式 { //這裏面定義一些白天模式下 控件的顏色屬性 也能夠定義其餘 _navColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1]; _bgColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1]; _btnColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1]; _textColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:1]; _btnTextColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1]; _navTextColor= [UIColor whiteColor]; } break; case nightTime://夜間模式 { //這裏面定義夜間模式下的相關控件的顏色屬性 _navColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1]; _bgColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:1]; _btnColor=[UIColor colorWithRed:10/255.0 green:85/255.0 blue:160/255.0 alpha:1]; _textColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1]; _btnTextColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1]; _navTextColor= [UIColor whiteColor]; } break; default: break; } } //發送更改主題的消息 +(void)postTopicChangeMessage{ [[NSNotificationCenter defaultCenter]postNotificationName:YHTopicChangeTopicNotication object:nil]; }
在manager調用通知中心發送通知後,咱們要讓全部須要改變主題的視圖控制器都接收到通知,最簡便的作法是,咱們設計一個父類,讓父類監聽通知,全部須要有主題更改功能的控制器繼承於它便可,這個father controller的核心代碼以下:
//移除監聽 -(void)dealloc{ [[NSNotificationCenter defaultCenter]removeObserver:self]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. //添加監聽主題更換的通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(useYHTopicToCreatViewWithModel) name:YHTopicChangeTopicNotication object:nil]; //協議中的方法,加載主題 一會再說 [self useYHTopicToCreatViewWithModel]; } //子類實現以下方法 -(void)useYHTopicToCreatViewWithModel{ }
到目前,咱們已經能夠順利接收到主題切換的通知,但是要全部子類都步伐一致的執行相同一個操做,咱們能夠經過一個協議來約定,這就是圖中的主框架的protocol,這個協議中規定一個特定的方法,咱們在父類中調用,子類中實現,當收到通知時,全部子類都將從新加載這個方法,若是咱們將皮膚設置部分在這個方法中實現,那麼正是咱們想要的效果,全部皮膚設置都被從新加載了。協議以下:
/** *這裏定義主題的風格 */ typedef enum { dayTime=1,//白天 nightTime//夜間 }YHTopicModel; @protocol YHTopicProcotol <NSObject> //全部能夠更換主題的界面必須遵照這個協議調用並實現以下方法 //將視圖中控件的顏色攝住部分所有放在這個方法中 @required -(void)useYHTopicToCreatViewWithModel; @end
這時,就剩下咱們這套邏輯的最後一步了,咱們只須要將控件的顏色設置寫在子類的協議方法中,而且,這些設置的數據來源於model這個模型,整個體系就完成了,子類實現方法以下:
-(void)useYHTopicToCreatViewWithModel{ //獲取到模型 YHTopicColorManager * model = [YHTopicColorManager sharedTheSingletion]; //加載模型數據 [model getTopicModel]; //進行設置 self.view.backgroundColor = model.bgColor; _schoolLabel.textColor = model.textColor; _phoneLabel.textColor = model.textColor; _secertLabel.textColor = model.textColor; _reWriteSecretLabel.textColor = model.textColor; _questionLabel.textColor = model.textColor; _answerLabel.textColor = model.textColor; _registBtn.backgroundColor = model.btnColor; [_registBtn setTitleColor:model.btnTextColor forState:UIControlStateNormal]; }
我簡單寫了一些界面,不論任何地方切換皮膚,全部界面效果都會改變:
切換夜間模式前:
開啓夜間模式後:
本身的思路實現更換主題的一種方法,真誠的想與志同道合的朋友交流開發經驗,若是你想批評,點撥,交流或者是借鑑個人代碼,Q316045346隨時歡迎。
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592