前天在做項目的時候, 遇到一個問題(夜間模式的實現),通常我們在設置夜間模式的時候,簡單的做法是使用通知的設計模式,改變各個頁面的背景色,然后設置一下透明的效果,可是一個真正的項目,並不能馬虎,需要頁面效果美觀精致。本文參考了github上一個老外寫的實現方案,方案參考 經過自己的理解整合,制作出了自己的頁面模式的實現。
Xcode中floder 與 group 的區別
在這里我先要說明一下:在Xcode中藍色和黃色文件夾的區別,因為本文就是使用到了藍色的文件夾,通常藍色文件夾在IOS中被稱為folder,他在項目中只能被稱為資源來使用,不能被編譯代碼。黃色文件夾被稱為group一般在工程中是文件夾的形式,但是在本地目錄里還是比較散亂的文件,為了更好地管理和規范一個工程的文件夾,請參考我的博文,一般先創建好工程的框架文件夾,然后拖入工程,選擇復制和創建,這樣再次新建的文件就會在對應的group文件夾中了。
實現的思路
將設置的夜間模式與日間模式的顏色RGB值分別寫入plist文件,將日間模式定為系統的默認模式。需要創建三個plist文件。pliast A 用來存放模式(日間/夜間);pliast B 用來存放日間模式下的RGB顏色值,寫入group中;plist C 用來存放夜間模式下的RGB的顏色值,寫入floder中。其中 B 與 C 中相同的顏色值名字 key 對應的Value值(RGB 值)是不一樣的,這樣在檢測到通知改變的時候,系統就根據當前的主題模式去根據路徑尋找對應的plist A 或者 B文件,然后通過一個將RGB值轉化為對應的顏色值的方法,進行改變頁面的顏色,不僅能改變背景色,也可以通過這個方法改變一些控件的顏色值,這樣就真正的實現了夜間模式,是不是有些麻煩呢?
圖1.存放日間,夜間模式的路徑
圖2.日間模式的顏色值
圖3.夜間模式的顏色值
下面我將會附上關鍵源代碼。
//更主題的通知 #define ThemeChangeNotification @"ThemeChangeNotification" //更改主題的通知 #define ThemeName @"ThemeName" //主題名稱 #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> @interface ConfigurationTheme : NSObject { @private //主題配置信息 NSDictionary * _themesConfig; } @property (copy, nonatomic) NSString *themeName; //當前使用的主題名稱 @property (strong, nonatomic) NSDictionary *themesConfig; //主題配置信息 @property (strong, nonatomic) NSDictionary *fontConfig; //字體的配置信息 //創建單例,確保該對象唯一 + (ConfigurationTheme *)shareInstance; //獲取當前主題下的圖片名稱 -(UIImage *)getThemeImageName:(NSString *)imageName; //獲取當前主題下的顏色 - (UIColor *)getThemeColorWithName:(NSString *)colorName; ConfigurationTheme.h
#import "ConfigurationTheme.h" @implementation ConfigurationTheme //創建單例,確保該對象唯一 + (ConfigurationTheme *)shareInstance{ static ConfigurationTheme *configuration = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ configuration = [ConfigurationTheme new]; }); return configuration; } //重寫init方法 -(id)init{ self = [super init]; if (self != nil) { //讀取主題配置文件 NSString *filePlist = [[NSBundle mainBundle] pathForResource:@"theme" ofType:@"plist"]; _themesConfig = [NSDictionary dictionaryWithContentsOfFile:filePlist]; //讀取字體配置文件 NSString *fontConfigPlist = [[NSBundle mainBundle] pathForResource:@"fontColor" ofType:@"plist"]; _fontConfig = [NSDictionary dictionaryWithContentsOfFile:fontConfigPlist]; self.themeName = @"默認"; } return self; } //得到當前主題名稱 - (void)setThemeName:(NSString *)themeName{ if (_themeName != themeName) { _themeName = [themeName copy]; } //獲取主題配置的根目錄 NSString * themePath = [self getThemePath]; NSString * filePath = [themePath stringByAppendingPathComponent:@"fontColor.plist"]; _fontConfig = [NSDictionary dictionaryWithContentsOfFile:filePath]; } //獲取當前主題配置的目錄 - (NSString *)getThemePath{ //項目的根路徑 NSString * resourcePath = [[NSBundle mainBundle] resourcePath]; if ([_themeName isEqualToString:@"默認"]) { return resourcePath; } //獲取當前主題的配置路徑 NSString *configurationPath = [_themesConfig objectForKey:_themeName]; //主題的完整路徑 NSString *themePath = [resourcePath stringByAppendingPathComponent:configurationPath]; return themePath; } //獲取當前主題下的圖片 -(UIImage *)getThemeImageName:(NSString *)imageName{ if (imageName.length == 0) { return nil; } //獲取當前主題配置的目錄 NSString *configurationPath = [self getThemePath]; //圖片名稱在當前主題的文件路徑 NSString *imagePath = [configurationPath stringByAppendingPathComponent:imageName]; UIImage *image = [UIImage imageWithContentsOfFile:imagePath]; return image; } //獲取當前主題下的顏色 - (UIColor *)getThemeColorWithName:(NSString *)colorName{ if (colorName.length == 0){ return nil; } NSString *rgb = [self.fontConfig objectForKey:colorName]; NSArray *rgbs = [rgb componentsSeparatedByString:@","]; if (rgbs.count == 3) { float r = [rgbs[0] floatValue]; float g = [rgbs[1] floatValue]; float b = [rgbs[2] floatValue]; UIColor *color = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]; return color; } return nil; } + (id)copyWithZone:(NSZone *)zone { return self; } @end ConfigurationTheme.m
#import "BaseNavigationController.h" @interface BaseNavigationController () @end @implementation BaseNavigationController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { //監聽主題切換的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themeNotification:) name:ThemeChangeNotification object:nil]; } return self; } - (void)themeNotification:(NSNotification *)notification { [self loadThemeImage]; } - (void)loadThemeImage { //使用顏色設置navigationBar的背景顏色 // self.navigationBar.barTintColor = [[ConfigurationTheme shareInstance] getThemeColorWithName:@"blColor"]; //使用背景圖片設置導航條 [self.navigationBar setBackgroundImage:[[ConfigurationTheme shareInstance] getThemeImageName:@"navigationbar_background.png"] forBarMetrics:UIBarMetricsDefault]; //設置導航欄字體顏色和大小 [self.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[[ConfigurationTheme shareInstance] getThemeColorWithName:@"ygColor"],NSForegroundColorAttributeName,[UIFont fontWithName:@"Helvetica" size:21.0],NSFontAttributeName,nil]]; } - (void)viewDidLoad{ [super viewDidLoad]; [self loadThemeImage]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; Kmemory } @end BaseNavigationController.m
日間模式和夜間模式: