背景
在做客户端APP时,时常有各种节假日的皮肤处理,让客户端要在某些公祭日的时候显示灰色,但又不要影响正常时间的性能前提下。如何处理类似这种布局与资源的显示?
理论方案
1、在每天第一次启动客户端时,请求一次服务端是否是公祭日或特殊的日子;数据中包函当前日期及是否是公祭日标识,以本地日期为键保存在本地。
2、如果是正常的日子可以继续后面执行;如果是公祭日或者特殊日子,动态重写需要改变的方法,以达到更改的效果。
实现方案(iOS实现,重点部分
)
1、在需要改变的资源文件读取的时候需要自定义方法实现,以便初始化时动态修改,也不会影响到其他地方。如UIImage
加载时,可以实现一个分类加上里面的方法或者自定义类与方法实现。
2、动态修改加载方法,可以通过对应类的+ (void)Load
方法进行方法替换,主要是方法替换前实现日期判断,如果正常日则不进行替换方法,否则替换原来的方法。
OC代码
#import "ViewController.h"
#import "UIImage+BBBaseKit.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage bb_imageNamed:@"loading_20.png"]];
imageView.frame = CGRectMake(0.f, 100.f, 200.f, 200.f);
[self.view addSubview:imageView];
}
@end
#import "UIImage+BBBaseKit.h"
@implementation UIImage(BBBaseKit)
+ (nullable UIImage *)bb_imageNamed:(NSString *)name {
return [self imageNamed:name];
}
@end
#import "UIImage+BBDemo.h"
#import "UIImage+BBBaseKit.h"
#import <objc/runtime.h>
#import <objc/message.h>
@implementation UIImage(BBDemo)
+ (void)load {
if (1) { //在此判断是否是特殊时间
Method newMethod = class_getClassMethod([self class], @selector(bb_imageNamed:));
Method method = class_getClassMethod([self class], @selector(bb_grayImage:));
method_exchangeImplementations(newMethod, method);
}
}
+ (UIImage *)bb_grayImage:(NSString *)name {
UIImage *sourceImage = [self imageNamed:name];
int width = sourceImage.size.width;
int height = sourceImage.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate (nil,width,height,8,0,colorSpace,kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (context == NULL) {
return nil;
}
CGContextDrawImage(context,CGRectMake(0, 0, width, height), sourceImage.CGImage);
UIImage *grayImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGContextRelease(context);
return grayImage;
}
@end