夜間模式的實現


前天在做項目的時候, 遇到一個問題(夜間模式的實現),通常我們在設置夜間模式的時候,簡單的做法是使用通知的設計模式,改變各個頁面的背景色,然后設置一下透明的效果,可是一個真正的項目,並不能馬虎,需要頁面效果美觀精致。本文參考了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

 

日間模式和夜間模式:

                        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM