夜间模式的实现

前天在做项目的时候, 遇到一个问题(夜间模式的实现),通常我们在设置夜间模式的时候,简单的做法是使用通知的设计模式,改变各个页面的背景色,然后设置一下透明的效果,可是一个真正的项目,并不能马虎,需要页面效果美观精致。本文参考了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

 

日间模式和夜间模式:

                        

posted @ 2016-01-03 23:05  ywda  阅读(2812)  评论(0编辑  收藏  举报