欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS屏幕截图事件

程序员文章站 2024-02-06 22:51:16
...

一直想做这个功能,相信完善后加入我们项目中,会很有效的方便用户截屏反馈问题。目前ios11版本已经有了屏幕截图编辑并分享的功能,现在才写有点多余了。
将截取到的图片放在当前页面中展示,初步利用程序截图并按一定比例显示在屏幕上。截图同时触发分享弹框,点击任意分享按钮则释放imgView并关闭视图。此处贴图暂未把分享功能加入,仅仅是个小demo。如下效果: iOS屏幕截图事件

首先第一步是考虑如何获取系统截屏的事件,查找之后发现苹果在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,请点附件下载

相关标签: ios 屏幕截图