最近在使用支付宝的过程中发现当支付宝运行在手机后台,我们双击Home键切换app的时候,支付宝为了保护用户隐私会添加模糊效果。自己就模仿着实现了一下,先说一下我的实现思路:
- 在window上直接添加一个就有毛玻璃效果的view。这种方式是可以就有保护用户隐私的作用的,但是,就是比较丑。它是直接在window上覆盖了一层具有毛玻璃效果view,view下面的完全看不见,不像支付宝那种具有模糊效果。这种方法不行。
- 支付宝的那种模糊效果,并不仅仅毛玻璃,而是图片的高斯模糊效果。所以,要想实现支付宝的效果,首先在app将要回到后台
- (void)applicationWillResignActive:(UIApplication *)application {
#pragma mark - 回到后台的时候截取当前屏幕
[[Screenshots sharedScreenshots]dataWithScreenshotInPNGFormat];
}
获取到当前window的截屏图片并保存到沙盒,然后在下面这个方法里面将你创建的覆盖window上view显示出来
>- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
self.bgView = [WindowAboveBackgroundView new];
[self.bgView show];
}
在app将药进入前台的时候将你创建覆盖在window上的view移除掉
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
[self.bgView hidden];
}
图片高斯模糊效果的实现
+ (UIImage *)coreGaussianBlurImage:(UIImage * _Nonnull)image blurNumber:(CGFloat)blur{
if (!image) {
return nil;
}
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:blur] forKey:@"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *blurImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return blurImage;
}
屏幕截图的实现
#pragma mark - 获得屏幕截图
- (BOOL)dataWithScreenshotInPNGFormat
{
CGSize imageSize = CGSizeZero;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsPortrait(orientation))
imageSize = [UIScreen mainScreen].bounds.size;
else
imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
CGContextSaveGState(context);
CGContextTranslateCTM(context, window.center.x, window.center.y);
CGContextConcatCTM(context, window.transform);
CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
if (orientation == UIInterfaceOrientationLandscapeLeft)
{
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, 0, -imageSize.width);
}
else if (orientation == UIInterfaceOrientationLandscapeRight)
{
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, 0);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
}
if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
{
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
}
else
{
[window.layer renderInContext:context];
}
CGContextRestoreGState(context);
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imgData = UIImagePNGRepresentation(image);
return [self writeFile:imgData];
}
保存沙盒的实现
#pragma mark - 将截屏保存到沙盒
- (BOOL)writeFile:(NSData *)file
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"pdf.jpg"];
NSError *error;
BOOL iswriteToFile = [file writeToFile:path options:NSDataWritingAtomic error:&error];
NSLog(@"56832%@",NSHomeDirectory());
return iswriteToFile;
}
读取沙盒截图的实现
#pragma mark - 读取沙盒里面保存的截图
- (UIImage *)readFile
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"pdf.jpg"];
NSData *imgData = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:imgData];
return image;
}
demo的传送门
如果对您有帮助,顺便给个✨吧!
网友评论