iOS 应用内截屏分享

需求:捕获用户截屏操作,并建议用户截屏后的操作。虽然iOS11 有系统的截屏,但 APP 内截屏可便捷操作。

封装工具类

实现功能:

  • 获取到截屏的图片
  • 展示截屏图片和相关操作
  • 定时器,规定时间后取消展示

tool.h

#import <Foundation/Foundation.h>

@interface LPScreenShotTool : NSObject
+ (instancetype) sharedScreenShot;
- (void)embedApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
@end

tool.m

#import "LPScreenShotTool.h"
@interface LPScreenShotTool()
@property (nonatomic, strong) UIView *shotView;
@property (nonatomic, weak) NSTimer *timer;//定时器
@property (nonatomic, assign) NSInteger timerNum;//定时器时间,用于循环
@end

@implementation LPScreenShotTool
static id _instace;
+ (instancetype) sharedScreenShot{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[LPScreenShotTool alloc]init];
    });
    return _instace;
}
+ (id)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}

- (id)copyWithZone:(NSZone *)zone {
    return _instace;
}
- (void)embedApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 注册截屏通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDidTakeScreenshot:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
}
// 执行截屏相应事件
//画 UI,处理功能,自定义代码
- (void)userDidTakeScreenshot:(NSNotification *)notification {
    UIImage *image = [self imageWithScreenshot];
    UIWindow *window = [[UIApplication sharedApplication].windows objectAtIndex:0];

    _shotView = [[UIView alloc] initWithFrame:CGRectMake(0, ScreenHeight-200, ScreenWidth, 200)];
    _shotView.backgroundColor = [BlueBGColor colorWithAlphaComponent:0.85];
    
    //添加显示
    UIImageView *imgPhoto = [[UIImageView alloc]initWithImage:image];
    imgPhoto.frame = CGRectMake(30, 15, 100, _shotView.height-30);
    //添加边框
    imgPhoto.layer.borderColor = [[UIColor whiteColor] CGColor];
    imgPhoto.layer.borderWidth = 1.0f;
//    //添加四个边阴影
//    imgvPhoto.layer.shadowColor   = [UIColor blackColor].CGColor;
//    imgvPhoto.layer.shadowOffset  = CGSizeMake(0, 0);
//    imgvPhoto.layer.shadowOpacity = 0.5;
//    imgvPhoto.layer.shadowRadius  = 10.0;
//    //添加两个边阴影
//    imgvPhoto.layer.shadowColor   = [UIColor blackColor].CGColor;
//    imgvPhoto.layer.shadowOffset  = CGSizeMake(4, 4);
//    imgvPhoto.layer.shadowOpacity = 0.5;
//    imgvPhoto.layer.shadowRadius  = 2.0;
    [_shotView addSubview:imgPhoto];
    [window addSubview:_shotView];
    _timerNum = 4;
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerStepStart) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
}
- (void)timerStepStart{
    if (_timerNum == 0) {
        if ([self.timer isValid]) {
            [self.timer invalidate];
            self.timer = nil;
            [_shotView removeFromSuperview];
        }
        return;
    }
    _timerNum = _timerNum - 1;
}
- (UIImage *)imageWithScreenshot {
    NSData *imageData = [self dataWithScreenshotInPNGFormat];
    return [UIImage imageWithData:imageData];
}
// 获取到截屏图片
- (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);
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIApplicationUserDidTakeScreenshotNotification" object:nil];
    
    [self.timer invalidate];
    self.timer = nil;
    [_shotView removeFromSuperview];
}

@end

如何引用

AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[LPScreenShotTool sharedScreenShot] embedApplication:application didFinishLaunchingWithOptions:launchOptions];
    return YES;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,061评论 25 707
  • 2017.1.16 武功山 前年,一行人计划四处漂流,却辗转多无定数。人生历...
    南方有南初阅读 530评论 0 5
  • 睁开眼睛 看到了黑夜 窗外滴滴答答的秋雨 屋子里的桌椅、茶杯、灯光都跑了 剩下的还是雨滴穿过阶石的唏嘘 触摸到的都...
    式微_fe7e阅读 205评论 0 0
  • 日子顺风顺水却被过的半死不活,你是不是问过自己:活着是为了什么?屡受挫折,事事不随人愿时,你是否问过自己:人...
    舒骅阅读 476评论 0 0
  • 贺年 , 万象更新开颜. 桔红春绿鸿运伴 闻鸡起舞抱负坚. 开年 , 金光灿烂眼前, 相约再会衣锦还, 到时煮酒庆凱旋.
    王卓族阅读 288评论 0 0