随着国家越来越多的公祭纪念活动,我们的app被要求在特定的时间全部灰色化,以配合国家公祭活动。悼念革命烈士,人民英雄。
经过多方查找资料研究,发现一个相对简单的方法。
首先引入以下Category文件,到项目中
引入之后把头文件引入到AppDelegate中, 然乎在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中写以下几个方法即可实现灰色
#import "AppDelegate.h"
#import "UIColor+LhGray.h"
#import "UIImage+GrayImage.h"
#import "UIImageView+GrayImageview.h"
#import "UITabBarItem+LhGray.h"
#import "WKWebView+LhGray.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//设置灰色模式
[UITabBarItem lh_tabbarItemSwizzldMethedWith:YES];
[UIColor lh_colorSwizzldColorMethedWith:YES];
[UIImage lh_imageSwizzldMethedWith:YES];
[UIImageView lh_imageViewSwizzldMethedWith:YES];
[WKWebView lh_WKWebViewWizzldMethedWith:YES];
return YES;
}
我只发.m文件
这个是颜色文件的分类
#import "UIColor+LhGray.h"
#import
@implementation UIColor (LhGray)
+(void)lh_colorSwizzldColorMethedWith:(BOOL)changeGray{
Class cls = object_getClass(self);
//将系统提供的colorWithRed:green:blue:alpha:替换掉
Method originMethod = class_getClassMethod(cls, @selector(colorWithRed:green:blue:alpha:));
Method swizzledMethod = class_getClassMethod(cls, @selector(lg_colorWithRed:green:blue:alpha:));
[self swizzleMethodWithOriginSel:@selector(colorWithRed:green:blue:alpha:) oriMethod:originMethod swizzledSel:@selector(lg_colorWithRed:green:blue:alpha:) swizzledMethod:swizzledMethod class:cls];
//将系统提供的colors也替换掉
NSArray *array = [NSArray arrayWithObjects:@"redColor",@"greenColor",@"blueColor",@"cyanColor",@"yellowColor",@"magentaColor",@"orangeColor",@"purpleColor",@"brownColor",@"systemBlueColor",@"systemGreenColor", nil];
for (int i = 0; i < array.count ; i ++) {
SEL sel = NSSelectorFromString(array[i]);
SEL lg_sel = NSSelectorFromString([NSString stringWithFormat:@"lg_%@",array[i]]);
Method originMethod = class_getClassMethod(cls, sel);
Method swizzledMethod = class_getClassMethod(cls, lg_sel);
[self swizzleMethodWithOriginSel:sel oriMethod:originMethod swizzledSel:lg_sel swizzledMethod:swizzledMethod class:cls];
}
}
+ (void)swizzleMethodWithOriginSel:(SEL)oriSel
oriMethod:(Method)oriMethod
swizzledSel:(SEL)swizzledSel
swizzledMethod:(Method)swizzledMethod
class:(Class)cls {
BOOL didAddMethod = class_addMethod(cls, oriSel, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(cls, swizzledSel, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
} else {
method_exchangeImplementations(oriMethod, swizzledMethod);
}
}
+ (UIColor *)lg_redColor {
// 1.0, 0.0, 0.0 RGB
UIColor *color = [self lg_redColor];
color = [self changeGrayWithColor:color Red:1.0 green:0.0 blue:0.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_greenColor {
// 0.0, 1.0, 0.0 RGB
UIColor *color = [self lg_greenColor];
color = [self changeGrayWithColor:color Red:0.0 green:1.0 blue:0.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_blueColor {
//0.0, 0.0, 1.0
UIColor *color = [self lg_blueColor];
color = [self changeGrayWithColor:color Red:0.0 green:0.0 blue:1.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_cyanColor {
// 0.0, 1.0, 1.0
UIColor *color = [self lg_cyanColor];
color = [self changeGrayWithColor:color Red:0.0 green:1.0 blue:1.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_yellowColor {
//1.0, 1.0, 0.0
UIColor *color = [self lg_yellowColor];
color = [self changeGrayWithColor:color Red:1.0 green:1.0 blue:0.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_magentaColor {
// 1.0, 0.0, 1.0
UIColor *color = [self lg_magentaColor];
color = [self changeGrayWithColor:color Red:1.0 green:0.0 blue:1.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_orangeColor {
// 1.0, 0.5, 0.0
UIColor *color = [self lg_orangeColor];
color = [self changeGrayWithColor:color Red:1.0 green:0.5 blue:0.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_systemBlueColor {
UIColor *color = [self lg_systemBlueColor];
color = [self changeGrayWithColor:color Red:0.0 green:0.0 blue:1.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_systemGreenColor {
UIColor *color = [self lg_systemGreenColor];
color = [self changeGrayWithColor:color Red:0.0 green:1.0 blue:0.0 alpha:1.0];
return color;
}
+ (UIColor *)lg_purpleColor {
// 0.5, 0.0, 0.5
UIColor *color = [self lg_purpleColor];
color = [self changeGrayWithColor:color Red:0.5 green:0.0 blue:0.5 alpha:1.0];
return color;
}
+ (UIColor *)lg_brownColor {
// 0.6, 0.4, 0.2
UIColor *color = [self lg_brownColor];
color = [self changeGrayWithColor:color Red:0.6 green:0.4 blue:0.2 alpha:1.0];
return color;
}
+ (instancetype)lg_colorWithRed:(CGFloat)r green:(CGFloat)g blue:(CGFloat)b alpha:(CGFloat)a {
UIColor *color = [self lg_colorWithRed:r green:g blue:b alpha:a];
if (r == 0 && g == 0 && b == 0) {
return color;
}
color = [self changeGrayWithColor:color Red:r green:g blue:b alpha:a];
return color;
}
+ (UIColor *)changeGrayWithColor:(UIColor *)color Red:(CGFloat)r green:(CGFloat)g blue:(CGFloat)b alpha:(CGFloat)a {
CGFloat gray = r * 0.299 +g * 0.587 + b * 0.114;
UIColor *grayColor = [UIColor colorWithWhite:gray alpha:a];
return grayColor;
}
@end
这个是image文件的分类
#import "UIImage+GrayImage.h"
@implementation UIImage (GrayImage)
+(void)lh_imageSwizzldMethedWith:(BOOL)changeGray{
if (changeGray == false) {
return;
}
//交换方法
Class cls = object_getClass(self);
Method originMethod = class_getClassMethod(cls, @selector(imageNamed:));
Method swizzledMethod = class_getClassMethod(cls, @selector(lg_imageNamed:));
[self swizzleMethodWithOriginSel:@selector(imageNamed:) oriMethod:originMethod swizzledSel:@selector(lg_imageNamed:) swizzledMethod:swizzledMethod class:cls];
Method originMethod1 = class_getClassMethod(cls, @selector(imageWithData:));
Method swizzledMethod1 = class_getClassMethod(cls, @selector(lg_imageWithData:));
[self swizzleMethodWithOriginSel:@selector(imageWithData:) oriMethod:originMethod1 swizzledSel:@selector(lg_imageWithData:) swizzledMethod:swizzledMethod1 class:cls];
}
+ (void)swizzleMethodWithOriginSel:(SEL)oriSel
oriMethod:(Method)oriMethod
swizzledSel:(SEL)swizzledSel
swizzledMethod:(Method)swizzledMethod
class:(Class)cls {
BOOL didAddMethod = class_addMethod(cls, oriSel, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(cls, swizzledSel, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
} else {
method_exchangeImplementations(oriMethod, swizzledMethod);
}
}
+ (UIImage *)lg_imageWithData:(NSData *)data {
UIImage *image = [self lg_imageWithData:data];
return [image grayImage];
}
+ (UIImage *)lg_imageNamed:(NSString *)name {
UIImage *image = [self lg_imageNamed:name];
return [image grayImage];
}
// 转化灰度
- (UIImage *)grayImage {
const int RED =1;
const int GREEN =2;
const int BLUE =3;
// Create image rectangle with current image width/height
CGRect imageRect = CGRectMake(0,0, self.size.width* self.scale, self.size.height* self.scale);
int width = imageRect.size.width;
int height = imageRect.size.height;
// the pixels will be painted to this array
uint32_t *pixels = (uint32_t*) malloc(width * height *sizeof(uint32_t));
// clear the pixels so any transparency is preserved
memset(pixels,0, width * height *sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// create a context with RGBA pixels
CGContextRef context = CGBitmapContextCreate(pixels, width, height,8, width *sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
// paint the bitmap to our context which will fill in the pixels array
CGContextDrawImage(context,CGRectMake(0,0, width, height), [self CGImage]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
uint8_t *rgbaPixel = (uint8_t*) &pixels[y * width + x];
// convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
uint32_t gray = 0.3 * rgbaPixel[RED] +0.59 * rgbaPixel[GREEN] +0.11 * rgbaPixel[BLUE];
// set the pixels to gray
rgbaPixel[RED] = gray;
rgbaPixel[GREEN] = gray;
rgbaPixel[BLUE] = gray;
}
}
// create a new CGImageRef from our context with the modified pixels
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// we're done with the context, color space, and pixels
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
// make a new UIImage to return
UIImage *resultUIImage = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:UIImageOrientationUp];
// we're done with image now too
CGImageRelease(imageRef);
return resultUIImage;
}
这个是UIImageView分类
#import "UIImageView+GrayImageview.h"
#import "UIImage+GrayImage.h"
#import
@implementation UIImageView (GrayImageview)
+(void)lh_imageViewSwizzldMethedWith:(BOOL)changeGray;{
if (changeGray == false) {
return;
}
Class class = [self class];
SEL originalSelector = @selector(setImage:);
SEL swizzledSelector = @selector(swizzled_setImage:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- (void)swizzled_setImage:(UIImage *)image {
//系统键盘处理(如果不过滤,这系统键盘字母背景是黑色)
if ([self.superview isKindOfClass:NSClassFromString(@"UIKBSplitImageView")]) {
[self swizzled_setImage:image];
return;
}
UIImage *im = [[image grayImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// UIImage *im = [image grayImage];
[self swizzled_setImage:im];
}
@end
这个是UITabBarItem分类
#import "UITabBarItem+LhGray.h"
#import
@implementation UITabBarItem (LhGray)
+ (void)lh_tabbarItemSwizzldMethedWith:(BOOL)changeGray{
if (changeGray == false) {
return;
}
Class cls = [self class];
SEL oriSel = @selector(setSelectedImage:);
SEL swizzldSel = @selector(lh_setTabbarItemImage:);
Method originMethed = class_getInstanceMethod(cls, oriSel);
Method swizzldMethed = class_getInstanceMethod(cls, swizzldSel);
BOOL isAddMethed = class_addMethod(cls, oriSel, method_getImplementation(swizzldMethed),method_getTypeEncoding(swizzldMethed));
if (isAddMethed) {
class_replaceMethod(cls, swizzldSel, method_getImplementation(originMethed), method_getTypeEncoding(originMethed));
}else{
method_exchangeImplementations(originMethed,swizzldMethed);
}
}
- (void)lh_setTabbarItemImage:(UIImage *)image {
UIImage *im = [[self imageToTransparent:image] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[self lh_setTabbarItemImage:im];
}
- (UIImage*)imageToTransparent:(UIImage*) image
{
// 分配内存
const int imageWidth = image.size.width;
const int imageHeight = image.size.height;
size_t bytesPerRow = imageWidth * 4;
uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
// 创建context
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
// 遍历像素
int pixelNum = imageWidth * imageHeight;
uint32_t* pCurPtr = rgbImageBuf;
for (int i = 0; i < pixelNum; i++, pCurPtr++)
{
uint8_t* ptr = (uint8_t*)pCurPtr;
if (ptr[3] < 50 && ptr[3] < 50 && ptr[1] < 50) {
ptr[0] = 0;
} else {
// 灰度算法
uint8_t gray = ptr[3] * 0.299 + ptr[2] * 0.587 + ptr[1] * 0.114;
ptr[3] = gray; //0~255
ptr[2] = gray;
ptr[1] = gray;
}
}
// 将内存转成image
CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,
kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,
NULL, true,kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
// 释放
CGImageRelease(imageRef);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return resultUIImage;
}
void ProviderReleaseData (void *info, const void *data, size_t size)
{
free((void*)data);
}
@end
这个是WKWebView分类
#import "WKWebView+LhGray.h"
#import
//#import "SCConst.h"
@implementation WKWebView (LhGray)
+(void)lh_WKWebViewWizzldMethedWith:(BOOL)changeGray{
if (changeGray == false) {
return;
}
Method originalMethod = class_getInstanceMethod([self class], @selector(initWithFrame:configuration:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(lg_initWithFrame:configuration:));
method_exchangeImplementations(originalMethod, swizzledMethod);
}
- (instancetype)lg_initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration {
// js脚本
NSString *jScript = @"var filter = '-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%); -ms-filter:grayscale(100%); -o-filter:grayscale(100%) filter:grayscale(100%);';document.getElementsByTagName('html')[0].style.filter = 'grayscale(100%)';";
// 注入
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *userController = [[WKUserContentController alloc] init];
[userController addUserScript:wkUScript];
// 配置对象
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = userController;
configuration = wkWebConfig;
WKWebView *webView = [self lg_initWithFrame:frame configuration:configuration];
return webView;
}
@end