iOS程序框架設計之皮膚切換功能
iOS程序框架設計之皮膚切換功能
一、引言
移動應用的開發中,有時我們會需要例如更換皮膚此類的功能,andorid采用xml配置UI的方式,這個問題或許還容易解決些,iOS的主要UI邏輯則是在代碼中控制的,如果沒有一個強大的框架方案,這個問題將變得非常棘手。網上也有很多諸如此類功能的優秀案例與框架,在這篇博客中,我與大家分享下我的解決方案,其中如果有不恰或者糟糕之處,希望與高人一起交流。
二、設計思路與框架
首先我的設計思路是采用通知的方式,原理可以如下理解為以下幾步:
1、在系統的通知中心注冊一個通知
2、所有需要更改皮膚功能的controller作為這個通知的監聽者
3、設計一個皮膚的model類
4、將controller中有關皮膚設置的屬性從model中取
5、在切換皮膚前更改皮膚model
6、發送更改皮膚的通知
上面的6個步驟是這整個框架的基本邏輯,框架無非是將這些邏輯進行優化與封裝。下面這張圖很爛,但是思路很清晰:
首先最上面是我設計的一個切換主題的manager,我這里的設計有個缺陷,我將manager和主題配置相關的model混合在了一起,寫的時候簡單了些,可這給框架的邏輯上帶來了混亂,所以我在圖中使用曲線和虛橢圓將其分離,manager來控制切換model的屬性,我們在controller中取model的屬性進行配置,這個manager的邏輯位置是交互時間與通知中心的橋梁。manager中的核心代碼如下:
//單例方法
+(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隨時歡迎。
來自:http://my.oschina.net/u/2340880/blog/495670