1.将接口返回的图片缓存到本地,由于写data到本地是耗时操作,为了不阻塞主线程,可开启子线程来做此操作

 dispatch_queue_t queue = dispatch_queue_create("cn.xxx.queue", DISPATCH_QUEUE_SERIAL);
// 异步存到沙盒
dispatch_async(queue, ^{ for (XWMainBtnSkinModel *skinM in self.models) { // btn_Bottom_4
NSString *path = [skinM.btnKey cacheDirWithSubpath:@"tabbar"]; // 下载图片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:skinM.img]]; [data writeToFile:path atomically:YES]; if([skinM.type isEqualToString:@""]){ // btn_Bottom_4_sel
NSString *selImgKey = [NSString stringWithFormat:@"%@_sel",skinM.btnKey];
NSString *selpath = [selImgKey cacheDirWithSubpath:@"tabbar"]; // 下载图片
NSData *selImgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:skinM.selImg]]; [selImgData writeToFile:selpath atomically:YES];
}
} });

2.将请求到的图片,保存到内存,并给UI控件赋值,此处以tabbar为例

    UIImage *img = [[UIImage alloc] init];
UIImage *selImg = [[UIImage alloc] init];
int i = ;
for (UITabBarItem *item in self.tabBar.items) {
if(isNet){// 如果是从网络上获取,要告诉系统是@2x的图片
img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imgs[i]]] scale:2.0];
selImg = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:selImgs[i]]] scale:2.0];
}else{
img = [UIImage imageNamed:imgs[i]];
selImg = [UIImage imageNamed:selImgs[i]];
} item.image = [img imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; item.selectedImage = [selImg imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
i++;
}

3.第二次打开app时,判断本地是否有缓存文件,如果有,就取之前缓存中的文件(这样用户体验更好,省去去网络上下载图片)

    if (!isExist) { // 如果cache/tabbar这个目录不存在,就用默认主题
[self setUpChildController:mainPage title:@"首页" image:@"img_btn_mainpage_normal.png" selectedImage:@"img_btn_mainpage_select.png"]; [self setUpChildController:departClass title:@"分类" image:@"img_btn_class_normal" selectedImage:@"img_btn_class_select"]; [self setUpChildController:theme title:@"" image:@"img_btn_theme" selectedImage:@"img_btn_theme"]; [self setUpChildController:message title:@"消息" image:@"img_btn_message_normal" selectedImage:@"img_btn_message_select"]; [self setUpChildController:me title:@"我" image:@"img_btn_me_normal" selectedImage:@"img_btn_me_select"]; self.selectedIndex = ; // 矫正TabBar图片位置,使之垂直居中显示
CGFloat offset = 3.0;
for (UITabBarItem *item in self.tabBar.items) {
item.imageInsets = UIEdgeInsetsMake(offset, , -offset, );
if([item.title isEqualToString:@""])
{
item.imageInsets = UIEdgeInsetsMake(, , -, );
}
}
} else { //存在 [self setUpNetDataChildController:mainPage title:@"首页" image:@"btn_Bottom_1" selectedImage:@"btn_Bottom_1_sel"];
[self setUpNetDataChildController:departClass title:@"分类" image:@"btn_Bottom_2" selectedImage:@"btn_Bottom_2_sel"];
[self setUpNetDataChildController:theme title:@"" image:@"btn_Bottom_3" selectedImage:@"btn_Bottom_3_sel"];
[self setUpNetDataChildController:message title:@"消息" image:@"btn_Bottom_4" selectedImage:@"btn_Bottom_4_sel"];
[self setUpNetDataChildController:me title:@"我" image:@"btn_Bottom_5" selectedImage:@"btn_Bottom_5_sel"]; self.selectedIndex = ; // 矫正TabBar图片位置,使之垂直居中显示
CGFloat offset = 3.0;
for (UITabBarItem *item in self.tabBar.items) {
item.imageInsets = UIEdgeInsetsMake(offset, , -offset, );
if([item.title isEqualToString:@""])
{
item.imageInsets = UIEdgeInsetsMake(, , -, );
}
} }

4.如果到了主题的过期时间,就应该切换回默认的主题:从接口中获取到主题到期时间,并设置定时器,当到期后,就删除本地缓存,并不在处理接口返回的图片数据。(直到接口中的到期时间重设,才处理接口中的图片)

    [[NetRequest request]dataRequest:nil apiURL:__getSkinBtnImg needToCache:nil completeBlock:^(id result) {

        self.models = [XWMainBtnSkinModel mj_objectArrayWithKeyValuesArray:result[@"btnImg"]];
if(self.models.count > ){ XWMainBtnSkinModel *model = self.models[];
NSDateFormatter *date=[[NSDateFormatter alloc] init];
// endTime: "2016-04-16 16:45:59"
[date setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; /**服务返回的主题到期时间*/
NSDate *d=[date dateFromString:model.endTime];
NSTimeInterval late = [d timeIntervalSince1970]; NSDate *now = [NSDate date];
NSTimeInterval nowtiem = [now timeIntervalSince1970];
NSTimeInterval cha = late - nowtiem;
/**到期时间和当前时间的差值*/
self.cha = cha;
// 定时器(到期了就切回之前的默认主题)
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:cha target:self selector:@selector(returnSkan) userInfo:nil repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];; if(self.cha <=){ // 时间过了就不处理接口返回的数据了
return ;
} if (!isExist) {//目录不存在(第一次从网络上直接获取图片)
// 通知更改主题
[[NSNotificationCenter defaultCenter] postNotificationName:@"change" object:self userInfo:@{@"info":self.models}]; // 将图片 写入本地缓存起来,第二次就不用从网络上获取
[self writeFileToCache]; NSMutableArray *imgs = [NSMutableArray array];
NSMutableArray *selImgs = [NSMutableArray array]; for (XWMainBtnSkinModel *model in self.models) {
if ([model.type isEqualToString:@""]) {
[imgs addObject:model.img];
[selImgs addObject:model.selImg];
}
}
[self setUpTabbarWithImgs:imgs selImgs:selImgs isNet:YES];
[self.view setNeedsLayout];
} }else { // 如果没有请求到数据,就删除网络数据
[self returnSkan];
} } failedBlock:^(id error) {
[SVProgressHUD showErrorWithStatus:error];
}];
// 到时间后,就换回之前的皮肤
- (void)returnSkan
{
if ([[NSFileManager defaultManager] fileExistsAtPath:self.fileCache]) { // 删除沙盒的数据
[[NSFileManager defaultManager] removeItemAtPath:self.fileCache error:NULL];
}
// 该切回之前的主题了
[[NSNotificationCenter defaultCenter] postNotificationName:@"cha" object:self userInfo:nil]; NSMutableArray *normalImgs = [NSMutableArray arrayWithArray:@[@"img_btn_mainpage_normal.png",@"img_btn_class_normal",@"img_btn_theme",@"img_btn_message_normal",@"img_btn_me_normal"]];
NSMutableArray *selImgs = [NSMutableArray arrayWithArray:@[@"img_btn_mainpage_select.png",@"img_btn_class_select",@"img_btn_theme",@"img_btn_message_select",@"img_btn_me_select"]]; [self setUpTabbarWithImgs:normalImgs selImgs:selImgs isNet:NO];
}

定时改变App主题的方案的更多相关文章

  1. 基于 Flutter 以两种方式实现App主题切换

    概述 App主题切换已经成为了一种流行的用户体验,丰富了应用整体UI视觉效果.例如,白天夜间模式切换.实现该功能的思想其实不难,就是将涉及主题的资源文件进行全局替换更新.说到这里,我想你肯定能联想到一 ...

  2. iOS论App推送方案

    1.APNS介绍(原生推送实现原理) 在iOS平台上,大部分应用是不允许在后台运行并连接网络的.在应用没有被运行的时候,只能通过 Apple Push Notification Service (AP ...

  3. 车载导航应用中基于Sketch UI主题定制方案的实现

    1.导读 关于应用的主题定制,相信大家或多或少都有接触,基本上,实现思路可以分为两类: 内置主题(应用内自定义style) 外部加载方式(资源apk形式.压缩资源.插件等) 其实,针对不同的主题定制实 ...

  4. 移动端调试 — Pure|微信环境调试方案|App环境调试方案

    Pure 详细参见: 中文文档:http://leeluolee.github.io/2014/10/24/use-puer-helpus-developer-frontend/ 源码:https:/ ...

  5. PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [4] 首页 APP 接口开发方案 ③ 定时读取缓存方式

    用于 linux 执行 crontab 命令生成缓存的文件 crop.php <?php //让crontab 定时执行的脚本程序 require_once 'db.php'; require_ ...

  6. Android主题切换方案总结

    所谓的主题切换,就是能够根据不同的设定,呈现不同风格的界面给用户,也就是所谓的换肤. 1.将主题包(图片与配置)存到SD卡上(可通过下载或手动放入指定目录),在代码里强制从本地文件创建图片与配置文字大 ...

  7. iOS开发之App主题切换完整解决方案(Swift版)

    本篇博客就来介绍一下iOS App中主题切换的常规做法,当然本篇博客中只是提到了一种主题切换的方法,当然还有其他方法,在此就不做过多赘述了.本篇博客中所涉及的Demo完全使用Swift3.0编写完成, ...

  8. vue+less换肤,主题切换方案

    新的项目对于客户自定义要求很高,然后换肤是其中一个很小的模块,经过了一段时间的摸索,看了许多文章,找到了几种方案. https://www.cnblogs.com/leiting/p/11203383 ...

  9. 改变linux默认配色方案(dircolors和dircolors-solarized使用)

    前言 前几天刚买了阿里云的云服务器,今天使用putty进入服务器,发现linux默认的bash配色实在太丑. 特别是文件夹显示为深蓝色,到了白天,和黑色背景一搭配,根本看不清文字. 好在在github ...

随机推荐

  1. RBAC角色权限控制

    RBAC角色权限控制 1. user (用户表) *  用户的基本信息(mid:用户信息id  如图) 2. node (节点表) * 页面(模块\控制器\方法) 3. role_node(角色.节点 ...

  2. java日期处理总结(二)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAzUAAAG1CAIAAABPoU1KAAAgAElEQVR4nOy9e1xU1d747znP9/V9nu

  3. storm之8:并行度

    (一)storm拓扑的并行度可以从以下4个维度进行设置:1.node(服务器):指一个storm集群中的supervisor服务器数量.2.worker(jvm进程):指整个拓扑中worker进程的总 ...

  4. 企业管理系统开发笔记(4)---后台登录_MVC过滤器

    在asp.net时代,我们通常需要在后台的每个页面进行判断用户是否登录的状态,不管是通过session还是通过windows身份验证还是表单验证方式等等方法来对用户登录进行判断跳转.但是在mvc时代, ...

  5. 使用IE滤镜实现css3中rgba让背景色透明的效果

    让背景透明,听上去不是挺容易的么? 让背景色透明,很容易想到opacity,要兼容IE的话只要加上filter:alpha(opacity=?)就行了,OK,看看这个例子. html: <div ...

  6. 编译的时候 c:\windows\assembly\ 卸载不掉

    easyhook 开始还可以调试,几次过后 其自己去找c:\windows\assembly\ 下的包,编译多少次都不行. c:\windows\assembly\  卸载不掉 cmd cd \win ...

  7. 搭建splinter+python环境时遇到的错误

    因为不想用urllib2了,没有用过splinter,今天就想试试,毕竟后者支持的功能更人性化/自动化. 1,安装splinter 安装过程很简单,安装了pip的话,执行: $ [sudo] pip ...

  8. http状态码有那些?分别代表是什么意思

    http状态码有那些?分别代表是什么意思? 简单版 [ 100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息 ...

  9. PullToRefreshListView 内嵌checkbox 数据丢失问题

    在PullToRefreshListView 内部内嵌了Checkbox如下图所示: 原本设计思路是:对CheckBox 进行 setOnCheckedChangeListener 监听 当Check ...

  10. 解决rsyslog 断电或者被kill 重发问题

    $InputFilePersistStateInterval 1 Specifies how often the state file shall be written when processing ...