iOS 监听系统截屏,快捷问题反馈 + 模拟系统截屏生成图片

167 阅读2分钟

开发快捷问题反馈入口,需要监听系统级的截屏事件,然后获取截屏图片快速跳转问题反馈入口。

因为iOS现在新的截屏事件并不会立即把图片存入相册,所以无法第一时间去相册获取图片,需要自己手动模拟截屏的动作,生成一张对应的图片。

这里写的是OC的版本,因为旧的项目用的是OC写的,这边事件写在私有库里,需要提供给OC和Swift的项目使用。

一、设计图(实际运行效果)

IMG_8752.PNG

如图所示,在监听系统截图的同时,生成对应的图片,弹出对应的问题反馈入口,延迟3秒后消失。

二、手动生成截屏图片

生成截屏图片的方法放在基础拓展库作为通用:


// 获取截屏UIImage
+ (UIImage *)imageWithScreenshot
{
    NSData *imageData = [self dataWithScreenshotInPNGFormat];
    return [UIImage imageWithData:imageData];
}

// 获取截屏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);
}

三、监听系统截屏,生成问题反馈快捷入口

viewDidLoad 中,添加监听截图通知

    // 监听截图动作
    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(userDidTakeScreenshot:)
    name:UIApplicationUserDidTakeScreenshotNotification object:nil];

添加 @selector(userDidTakeScreenshot:) 事件,触发截屏+快捷问题反馈

#pragma mark - 监听屏幕截图,快捷问题反馈
- (void)userDidTakeScreenshot:(NSNotification *)notification
{
    NSLog(@"检测到截屏");
    // 人为截屏, 模拟用户截屏行为, 获取所截图片
    UIImage *image_ = [UIImage imageWithScreenshot];
    // 容器
    UIView *contentView = [[UIView alloc]initWithFrame:CGRectMake(self.view.frame.size.width - 64 - 15, (self.view.frame.size.height - 158)/2.0, 64, 158)];
    [contentView setUserInteractionEnabled:YES];
    
    // 添加显示
    UIImageView *imgvPhoto = [[UIImageView alloc]initWithImage:image_];
    imgvPhoto.frame = CGRectMake(0, 0, 64, 125);
    imgvPhoto.layer.cornerRadius = 4.0f;
    imgvPhoto.layer.masksToBounds = YES;
    
    CALayer * layer = [imgvPhoto layer];
    layer.borderColor = [[UIColor whiteColor] CGColor];
    layer.borderWidth = 4.0f;
    layer.cornerRadius = 4.0f;
    //添加四个边阴影
    imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
    imgvPhoto.layer.shadowOffset = CGSizeMake(0, 2);
    imgvPhoto.layer.shadowOpacity = 1;
    imgvPhoto.layer.shadowRadius = 4;
    [contentView addSubview:imgvPhoto];
    
    
    // 添加反馈按钮
    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 130, 64, 28)];
    button.backgroundColor = [UIColor hexStringToColor:@"#000000" alpha:0.5];
    [button cornerRadisus:4];
    [button setTitle:@"问题反馈" forState:UIControlStateNormal];
    button.titleLabel.font = [UIFont systemFontOfSize:12];
    [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
    [button addTarget:self action:@selector(questionShare) forControlEvents:UIControlEventTouchUpInside];
    [button setUserInteractionEnabled:YES];
    [contentView addSubview:button];
    
    [self.view addSubview:contentView];
    
    // 5秒后移除快捷问题反馈
    WEAKSELF
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [UIView animateWithDuration:0.5 animations:^{
            STRONGSELF
            // 渐渐移出屏幕
            [contentView setX:strongSelf.view.frame.size.width + 15.0];
        } completion:^(BOOL finished) {
            STRONGSELF
            if (finished) {
                [contentView removeFromSuperview];
            }
        }];
    });
}

/// 截图问题反馈
- (void)questionShare
{

}

最后,就简单的完成了快捷问题反馈的功能开发!可喜可贺~

最最最后,完结撒花

告辞.jpeg