App项目紧急加入整体页面置灰处理,这个功能呢,其实还算比较常规吧,在一些特殊日子中,为了悼念,大部分App会有置灰操作,有些只置灰首页,有的是置灰整体页面。
对于置灰操作,如果是每次都更新版本,肯定就来不及,一般处理方式为后台设置按钮开关,处理对应日子开启置灰操作。由于是后台处理,通过接口返回结果,那么看下iOS端实现方法
1.使用runtime方法交换机制处理,以图片加载为例
+ (void)load {
Method originalMethod = class_getInstanceMethod([self class], @selector(setImage:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(custom_setImage:));
method_exchangeImplementations(customMethod, originMethod);//方法交换
}
- (void)custom_setImage:(UIImage *)image {
//读取接口返回是否置灰
if (DEFAULTES_GET_OBJECT(@"isGrey")) {
[self custom_setImage:[self change_greyImage:image]];
} else {
[self custom_setImage:image];
}
}
- (UIImage *)change_greyImage:(UIImage *)image {
//UIKBSplitImageView是为了键盘
if (image == nil || [self.superview isKindOfClass:NSClassFromString(@"UIKBSplitImageView")]) {
return image;
}
//滤镜处理
//CIPhotoEffectNoir黑白
//CIPhotoEffectMono单色
NSString *filterName = @"CIPhotoEffectMono";
CIFilter *filter = [CIFilter filterWithName:filterName];
CIImage *inputImage = [[CIImage alloc] initWithImage:image];
[filter setValue:inputImage forKey:kCIInputImageKey];
CGImageRef cgImage = [self.filterContext createCGImage:filter.outputImage fromRect:[inputImage extent]];
UIImage *resultImg = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultImg;
}
- (CIContext *)filterContext {
CIContext *con = objc_getAssociatedObject(self, @selector(filterContext));
if (!con) {
con = [[CIContext alloc] initWithOptions:nil];
self.filterContext = con;
}
return con;
}
- (void)setFilterContext:(CIContext *)filterContext {
objc_setAssociatedObject(self, @selector(filterContext), filterContext, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
2.添加一个view,里面不接收任何点击事件(该做法只支持iOS12及12以上,根据实际情况使用)
@interface UIGreyViewOverLay : UIView
@end
@implementation UIGreyViewOverLay
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
return nil;
}
@end
//使用,把他直接覆盖在最顶层window.view即可:
- (void)initLaunchViewController{
UIView *contentView = [AppDelegate defaultView];
//app整体置灰
if (DEFAULTES_GET_OBJECT(@"isGrey")){
UIViewOverLay *overlay = [[UIViewOverLay alloc]initWithFrame:self.window.bounds];
overlay.translatesAutoresizingMaskIntoConstraints = false;
overlay.backgroundColor = [UIColor lightGrayColor];
overlay.layer.compositingFilter = @"saturationBlendMode";
[contentView addSubview:overlay];
}
LaunchViewController *launchController = [[LaunchViewController alloc]init];
[contentView addSubview:launchController.view];
launchController.view.frame = contentView.frame;
}
+ (UIView *)defaultView {
UIView *view;
for (UIWindow * window in [UIApplication sharedApplication].windows) {
if (!window.hidden
&& (window.windowLevel < UIWindowLevelStatusBar)) {
view = window;
}
}
return view;
}