iOS皮肤适配

皮肤配置文件创建

1、皮肤颜色资源和图片路径配置

皮肤配置文件

如图所示,创建 light.json 和 dark.json ( light 和 dark 配置路径key 一样,对应的value 不同)

light.json 配置示例

{
    "statusBarStyle": "black",
    "colors":{
        "mainFunction":"#E92424",
        "gradientStockUp":[
            "#0FFFFFFF",
            "#0FE92424"
        ]
    },
    "images": {
        "selfStock_info_icon": "appres/skinImage/light/selfStock_info_icon.png",
        "selfStock_money_icon": "appres/skinImage/light/selfStock_money_icon.png",
      }
      
 // appres/skinImage/light/selfStock_info_icon.png 对应的图片文件夹路径
}

dark.json 配置示例

{
    "statusBarStyle": "red",
    "colors":{
        "mainFunction":"#BC935C",
        "gradientStockUp":[
            "#26171717",
            "#26E92424"
        ]
    },
    "images": {
        "selfStock_info_icon": "appres/skinImage/dark/selfStock_info_icon.png",
        "selfStock_money_icon": "appres/skinImage/dark/selfStock_money_icon.png",
      }
}

2、设置全局的colorKey 来对应颜色路径 imageKey 来对应图片路径,利于维护

颜色key配置
图片key配置

皮肤使用

1、获取皮肤资源协议方法

// 获取皮肤资源协议方法
- (HJThemeDataModel *)getThemeModelWithName:(NSString *)name {
    NSString *path = [NSString stringWithFormat:@"appres/theme/%@",name];
    NSDictionary *colorDic = [self getDictFromJsonName:path][@"colors"];
    NSDictionary *imageDic = [self getDictFromJsonName:path][@"images"];
    HJThemeDataModel *model = [HJThemeDataModel new];
    model.colorDic = colorDic;
    model.imageDic = imageDic;
    return model;
}

/// 设置默认主题(使用皮肤,至少有一个默认皮肤)
- (HJThemeDataModel *)getDefaultThemeModel {
    return [self getThemeModelWithName:@"light"];
}

2、皮肤使用

// 导入头文件
#import "HJThemeManager.h"

// 设置当前皮肤 或切换 皮肤为 @"light"
[[HJThemeManager sharedInstance] switchThemeWithName:@"light"];

// 设置当前view 的背景色
//1、适配皮肤
self.view.themeBackgroundColor = backgroundColorKey; 
//2、不适配皮肤,必须带#号
self.view.themeBackgroundColor = @“#333333”; 
//3、适配皮肤,随皮肤变化
self.view.themeBackgroundColor = [HJThemeManager getThemeColor:backgroundColorKey]; 
//4、指定皮肤,不会随皮肤变化
self.view.themeBackgroundColor = [HJThemeManager getThemeColor:backgroundColorKey themeName:@"light"]; 

/**
  * [HJThemeManager getThemeColor:backgroundColorKey];
  * 实质上是 theme://"backgroundColorKey"?
  * 
  * [HJThemeManager getThemeColor:backgroundColorKey themeName:@"light"]; 
  * 实质上是 theme://"backgroundColorKey"?themeName=light
  */
//所以可以直接写URL 例如:
self.view.themeBackgroundColor = theme://backgroundColorKey?themeName=light;

// 设置当前imageView 的image
//1、适配皮肤
imageView.themeImage = imageKey; 
//2、适配皮肤,随皮肤变化
imageView.themeImage = [HJThemeManager getThemeImage:imageKey]; 
//3、指定皮肤,不会随皮肤变化
imageView.themeImage = [HJThemeManager getThemeImage:imageKey themeName:@"light"]; 

/**
  * [HJThemeManager getThemeImage:imageKey];
  * 实质上是 theme://"imageKey"?
  * 
  * [HJThemeManager getThemeImage:imageKey themeName:@"light"]; 
  * 实质上是 theme://"imageKey"?themeName=light
  */

//完整写法,指定皮肤
imageView.themeImage = theme://"imageKey"?themeName=light; 

//  兼容不适配皮肤写法
//  imageNamed 加载图片
imageView.themeImage = bundle://"imageKey"; 
//  sdwebimage 解析 http/https 加载图片
imageView.themeImage = http://imagePath; 
//  使用serverManager  getimage 的协议方法获取图片
imageView.themeImage = imagePath; 

3、皮肤的实现原理
1、创建一个NSObject分类(category),然后关联一个字典属性(themes),用于进行缓存UI控件调用的颜色方法和参数或者是图片方法和参数。再关联属性的时候添加一个通知监听,用于切换皮肤时,发送通知,然后再次调用缓存的方法和参数,进行颜色和图片的更换。

2、创建UI控件的分类(category),然后每个分类都有themes字典,然后设置新的方法来设置颜色或图片。在该方法内,需要做的处理有:

颜色举例说明:themeBackgroundColor = colorKey

a、在 themeBackgroundColor 的set方法中,判断是否是皮肤设置,皮肤的设置都是带有 theme:// 的字符串。这个(theme://)字符串是约定的。
b、皮肤适配模式,即带有 theme:// 字符串,就会用 themes 字典保存 系统的方法setBackgroundColor: 方法和参数colorKeythemeName,当切换皮肤时,再次调用 setBackgroundColor: 方法和参数colorKeythemeName
c、@"#333333", 直接是色值方法的 不需要 themes 字典保存,只需要直接调用系统方法 setBackgroundColor:[UIColor colorFromHexString:@"#333333"];

图片举例说明:imageView.themeImage = imageKey

a、在 themeImage 的set方法中,判断是否是皮肤设置,皮肤的设置都是带有 theme:// 的字符串。这个(theme://)字符串是约定的。
b、皮肤适配模式,即带有 theme:// 字符串,就会用 themes 字典保存 系统的方法setImage: 方法和参数imageKeythemeName,当切换皮肤时,再次调用 setImage: 方法和参数imageKeythemeName
c、bundle://, 直接是调用系统方法setImage:[UIImage imageNamed:@"imageNamed"] 进行赋值,不需要进行 themes 字典保存处理;
d、http:// 或 https:// , 采用SD框架加载图片,不需要进行 themes 字典保存处理;

3、主要的UI控件的分类

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface UIView (CMSThemeView)

/// 设置皮肤文件名称 默认为空值,取当前皮肤
/// 可以设置指定皮肤  例如:  @"Dark" / @"Light" ;
/// defaultThemeKey 为默认皮肤
/// 如何设置  Color 或 Image 有 themeName ,优先使用 themeName 
指定皮肤
@property (nonatomic, copy) NSString *themeStyle;
@property (nonatomic, copy) NSString *themeBackgroundColor;
@property (nonatomic, copy) NSString *themeTintColor;
/// 根据路径获取color 并缓存方法和参数 ()
- (void)setThemeColorWithIvarName:(NSString *)ivarName colorPath:(NSString *)path;
@end

@interface UILabel (ThemeLabel)
@property (nonatomic, copy) NSString *themeTextColor;
@property (nonatomic, copy) NSString *themeHighlightedTextColor;
@property (nonatomic, copy) NSString *themeShadowColor;
/// 主要是颜色
@property (nonatomic, strong) NSAttributedString *themeAttributedText;
@end

@interface UITextField (ThemeTextField)
@property (nonatomic, copy) NSString *themeTextColor;
@end

@interface UIImageView (CMSThemeImageView)
@property (nonatomic, copy) NSString *themeImage;

// 带有 UIImageRenderingMode 的处理,image 修改渲染色的,即tintColor
- (void)themeSetImageKey:(NSString *)imageKey
               renderingMode:(UIImageRenderingMode)mode;

@end

@interface UIButton (ThemeButton)

- (void)themeSetImage:(NSString *)path forState:(UIControlState)state;
- (void)themeSetImage:(NSString *)path forState:(UIControlState)state renderingMode:(UIImageRenderingMode)mode;
- (void)themeSetBackgroundImage:(NSString *)path forState:(UIControlState)state;
- (void)themeSetTitleColor:(NSString *)path forState:(UIControlState)state;
@end

@interface UITableView (ThemeTableView)
@property (nonatomic, copy) NSString *themeSeparatorColor;
@end

@interface CALayer (ThemeLayer)
/// 设置皮肤文件名称 默认为空值,取当前皮肤  eg:  @"Dark" / @"Light" ; defaultThemeKey 为默认皮肤
@property (nonatomic, copy) NSString *themeStyle;
@property (nonatomic, copy) NSString *themeBackgroundColor;
@property (nonatomic, copy) NSString *themeBorderColor;
@property (nonatomic, copy) NSString *themeShadowColor;
/// 根据路径获取cgcolor 并缓存方法和参数 ()
- (void)setThemeCGColorWithIvarName:(NSString *)ivarName colorPath:(NSString *)path;
@end

以上是简单列举了几个,其他UIKIt 控件一样分类处理即可

皮肤颜色流程图

皮肤颜色流程图

皮肤图片流程图

皮肤图片流程图

存在的缺陷

1、不能全局统一处理,需要一处一处的设置,比较麻烦。
2、目前还不支持网络下载皮肤功能,需要其他位置处理下载解压过程。
3、XIB的使用还需要其他的处理,这个比较重要

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容

  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,609评论 1 180
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 124,649评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,042评论 0 4