一直想做这个功能,相信完善后加入我们项目中,会很有效的方便用户截屏反馈问题。目前ios11版本已经有了屏幕截图编辑并分享的功能,现在才写有点多余了。
将截取到的图片放在当前页面中展示,初步利用程序截图并按一定比例显示在屏幕上。截图同时触发分享弹框,点击任意分享按钮则释放imgView并关闭视图。此处贴图暂未把分享功能加入,仅仅是个小demo。如下效果:
首先第一步是考虑如何获取系统截屏的事件,查找之后发现苹果在ios7之后提供了一个新的通知类型:UIApplicationUserDidTakeScreenshotNotification,这个通知会告知注册了此通知的对象已经发生了截屏事件,然后我们就可以在这个事件中实现自己的逻辑。
一、注册通知
+ (AppDelegate* )shareAppDelegate
{
// 发送通知信息
[[NSNotificationCenter defaultCenter] postNotificationName:@"Screens" object:nil userInfo:@{@"ScreensState":[NSNumber numberWithBool:YES]}];
return (AppDelegate*)[UIApplication sharedApplication].delegate;
}
在APPDelegate.h中声明+ (AppDelegate* )shareAppDelegate;
二、实现接收到通知的方法
我们需要创建一个UIView来显示截到的图片
#import "showView.h"
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
@interface showView ()
+ (instancetype)instance;
@property (nonatomic ,strong) UIImageView *_imgView;
@property (nonatomic ,strong) UIWindow *_window;
@property (nonatomic ,strong) UIButton *_btn;
@end
@implementation showView
static showView *instance;
+ (instancetype)instance
{
if (!instance)
{
instance = [[showView alloc] init];
}
return instance;
}
- (instancetype)init
{
if ((self = [super initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)]))
{
self.backgroundColor = [UIColor clearColor];
if (self.window == nil)
{
self._window = [[UIWindow alloc] init];
self._window.frame = self.frame;
self._window.windowLevel = UIWindowLevelAlert+1;
self._window.backgroundColor = [UIColor blackColor];
self._window.alpha = .5;
[self._window addSubview:self];
[self._window makeKeyAndVisible];
}
self._imgView = [[UIImageView alloc] init];
self._imgView.frame = CGRectMake(0, 0, kScreenWidth-80, (kScreenWidth-80)*kScreenHeight/kScreenWidth);//尺寸按屏幕比例截图比较美观
self._imgView.center = self.center;
[self addSubview:self._imgView];
//此处只是设置了一个取消按钮(removeFromSuperview)用以关闭弹框
self._btn = [UIButton buttonWithType:UIButtonTypeCustom];
self._btn.backgroundColor = [UIColor blueColor];
self._btn.frame = CGRectMake((self.frame.size.width - 100)/2, self.frame.size.height - 60, 100, 50);
[self._btn setTitle:@"点击" forState:UIControlStateNormal];
[self._btn addTarget:self action:@selector(dismissView) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self._btn];
}
return self;
}
+ (void)showWelcomeView:(UIImage *)images
{
[self instance];
instance._imgView.image = images;
}
- (void)dismissView
{
[self removeFromSuperview];
instance = nil;
}
三、实现截图的关键代码
写在APPdelegate.m实现全局调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//查找之后发现苹果在ios7之后提供了一个新的通知类型:UIApplicationUserDidTakeScreenshotNotification,这个通知会告知注册了此通知的对象已经发生了截屏事件,然后我们就可以在这个事件中实现自己的逻辑。
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationUserDidTakeScreenshotNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
// executes after screenshot
NSLog(@"截屏咯");
[self userDidTakeScreenshot];
}];
return YES;
}
//截屏响应
- (void)userDidTakeScreenshot
{
NSLog(@"检测到截屏");
//人为截屏, 模拟用户截屏行为, 获取所截图片
UIImage *image = [self imageWithScreenshot];
[showView showWelcomeView:image];//此处调用之前创建的用于显示截图的UIView,showView
}
/** * 返回截取到的图片 * * @return UIImage * */
- (UIImage *)imageWithScreenshot
{
NSData *imageData = [self dataWithScreenshotInPNGFormat];
return [UIImage imageWithData:imageData];
}
/** * 截取当前屏幕 * * @return NSData * */
- (NSData *)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();
return UIImagePNGRepresentation(image);
}
分享的方法在这里就不赘述了,网上一搜一大堆。
如需要demo,请点附件下载