手机截屏直接分享&反馈

前言

       目前市面上的一些主流App,比如:京东、淘宝、支付宝 等,他们都含所有手机截屏分享或者反馈的功能。它们实现这个功能的作用到底为了什么?个人感觉是:为了满足App的应用需求,同时更重要的是用户不用在点击手机的【Home】键返回到主页,再打开WeChat、QQ、Sina等App在找到我们截取的图片在进行反馈和分享。那么这个功能怎么实现呢?请您往下看……

一 、题为手机截屏,那怎么知道手机截屏了呢?

       首先这也是我们要首先介绍的一个重要功能。在我们的 UIKit 里面的  UIApplication.h  中有一个通知的Key。该通知如下:

// This notification is posted after the user takes a screenshot (for example by pressing both the home and lock screen buttons)
UIKIT_EXTERN NSNotificationName const UIApplicationUserDidTakeScreenshotNotification NS_AVAILABLE_IOS(7_0);

通过上面方法的说明可以知道当我们同时按住  Home  和 锁屏键系统就会触发该通知。那么为了能够在整个App中都能实现触发该通知,我们就在 App 的  AppDelegate.h  中添加监控该通知的代码,如下:

**/**!
 添加截屏事件的观察者
 */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenshotsEventMethod) name:UIApplicationUserDidTakeScreenshotNotification object:nil];**

二、我们已经知道用户触发了截屏,那么截屏功能怎么实现呢?

1、我们首先创建一个大小都为 0 的  CGSize  实例。代码如下:

CGSize imageSize = CGSizeZero ;

2、首先截屏我们要知道当前用户的手机是处于那种方向(竖屏&横屏),并确定截屏的图像 CGSize 的大小。代码如下:

/**
 确定当前屏幕的方向
 */
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);
}

3、我们通过 CGSize  开启图像的上下文,在有图像的  View   获得 CGContextRef  上下文。代码如下:

/**
 开启图像上下文,并设置上下文
 */
UIGraphicsBeginImageContext(imageSize);
/**
 获得上下文
 */
CGContextRef cContext = UIGraphicsGetCurrentContext() ;

4、通过遍历 App视图显示当前的所有窗口,来获取截取的图像。关键代码如下:

for (UIWindow * tempWindow in [UIApplication sharedApplication].windows) {
    /**
     先保存上下文,便于恢复场景
     */
    CGContextSaveGState(cContext) ;
    /**
     调整上下文的位置
     */
    CGContextTranslateCTM(cContext, tempWindow.center.x, tempWindow.center.y) ;
    /**
     生成仿射矩阵
     */
    CGContextConcatCTM(cContext, tempWindow.transform) ;
    /**
     调整位置
     */
    CGContextTranslateCTM(cContext, -tempWindow.bounds.size.width * tempWindow.layer.anchorPoint.x, -tempWindow.bounds.size.height * tempWindow.layer.anchorPoint.y);
    /**
     根据方向调整上下文
     */
    if (orientation == UIInterfaceOrientationLandscapeLeft){
        CGContextRotateCTM(cContext, M_PI_2);
        CGContextTranslateCTM(cContext, 0, -imageSize.width);
    } else if (orientation == UIInterfaceOrientationLandscapeRight){
        CGContextRotateCTM(cContext, -M_PI_2);
        CGContextTranslateCTM(cContext, -imageSize.height, 0);
    } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
        CGContextRotateCTM(cContext, M_PI);
        CGContextTranslateCTM(cContext, -imageSize.width, -imageSize.height);
    }
    /**
     判断是否呈现完整的快照视图层次为屏幕上可见到当前上下文。
     */
    if ([tempWindow respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){
        [tempWindow drawViewHierarchyInRect:tempWindow.bounds afterScreenUpdates:YES];
    } else {
        [tempWindow.layer renderInContext:cContext];
    }
    /**
     恢复上下文场景
     */
    CGContextRestoreGState(cContext);
}

5、通过上下文获取去截取的图像,并关闭图像的上下文。代码如下:

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

通过上面两个大的步骤,我们就能获取到用户截屏的图像。

三、获取到用户截屏的图像,那就可以实现自己的功能。

       我们这里介绍分享截屏对于App的开发人员来说,自己都有自己使用分享的一套。这里我们介绍我的分享SDK。

第1步、   我们首先下载 NWShareSDK 。
第2步、   我们讲下的 NWShareSDK 导入到您的 Project 里面。
第3步、   我们添加必要的支持库,如下图:

这里写图片描述

第4步、   我们添加支持分享的白名单,否则将不能打开WeChat\QQ\Sina等。如图粉色方框所示:

这里写图片描述

第5步、   我们支持分享回调,添加必要的 * URL Types * ,如图所示:

这里写图片描述
注意:以上的 URL Schemes 都是我自己编的。请把您的填入进去。然后在 * AppDelegate * 中实现回调的方法即可。

第6步、   在我们下载的 NWShareSDK 中含有 NWScreenshotsModule ,这就是我们截屏分享模块。如图所示:

这里写图片描述

第7步 、   在我们检测到手势截屏的通知触发的方法里面植入 ScreenshotsShareView 即可实现截屏分享。代码如下:
#pragma mark   Screenshots to trigger method
-(void)screenshotsEventMethod{
    ScreenshotsShareView * SSView = [[ScreenshotsShareView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    [[UIApplication sharedApplication].keyWindow addSubview:SSView];
}

ScreenshotsShareView 的代码如下:

//
//  ScreenshotsShareView.m
//  NetWork_NewShareDemo
//
//  Created by MAC on 2017/7/10.
//  Copyright © 2017年 NetworkCode小贱. All rights reserved.
//

#import "ScreenshotsShareView.h"

@implementation ScreenshotsShareView

-(instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        /**
         设置背景色
         */
        self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5];
        /**
         添加手势
         */
        UITapGestureRecognizer * tapGestureRecognizer  = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGestureMethod)];
        [self addGestureRecognizer:tapGestureRecognizer];
        /**
         内置定时器
         */
        __weak typeof(self) rootSelf = self ;
        NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:5 repeats:NO block:^(NSTimer * _Nonnull timer) {
            [rootSelf tapGestureMethod];
        }];
        /**
         动态注册标记
         */
        objc_setAssociatedObject(self, @"Timer", timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        /**
         添加弹出层
         */
        shareShowView = [[UIView alloc]init];
        shareShowView.layer.masksToBounds = YES ;
        shareShowView.layer.cornerRadius =  4 ;
        shareShowView.layer.borderWidth = 0.46 ;
        shareShowView.layer.borderColor = [UIColor grayColor].CGColor;
        [self addSubview:shareShowView];
    }
    return  self ;
}


#pragma mark 布局位置
-(void)layoutSubviews{
    shareShowView.frame = CGRectMake(0, 0, self.bounds.size.width * 0.628, 50);
    shareShowView.center = CGPointMake(self.center.x, CGRectGetHeight(self.frame)-80);
    /**
     分享内容的布局
     */
    [self makeShareIcon];
}


#pragma mark Set the share icons
-(void)makeShareIcon{
    /**
     添加标题
     */
    UILabel * shareTitleLable = [[UILabel alloc]initWithFrame:CGRectMake(5, 2.5, 20, 45)];
    shareTitleLable.font = [UIFont systemFontOfSize:10.0];
    shareTitleLable.text = @"分享至";
    shareTitleLable.numberOfLines =  3 ;
    [shareShowView addSubview:shareTitleLable];

    /**
     分享的Icons
     */
    NSArray * iconNamesArray = @[[UIImage imageNamed:@"ShareAction.bundle/weichat"],[UIImage imageNamed:@"ShareAction.bundle/friends"],[UIImage imageNamed:@"ShareAction.bundle/qq"],[UIImage imageNamed:@"ShareAction.bundle/sina"]];
    /**
     计算一个Icon 的宽度
     */
    CGFloat iconWidth = (CGRectGetWidth(shareShowView.frame) - 20 - CGRectGetWidth(shareTitleLable.frame) - (iconNamesArray.count - 1 )* 15 )/ iconNamesArray.count ;
    for (NSInteger i = 0; i < iconNamesArray.count; i++ ) {
        UIButton * iconBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        iconBtn.frame = CGRectMake(CGRectGetMaxX(shareTitleLable.frame)+10+ i * (iconWidth + 15) , 0.5 * (CGRectGetHeight(shareShowView.frame) - iconWidth ), iconWidth , iconWidth);
        [iconBtn setImage:iconNamesArray[i] forState:UIControlStateNormal];
        iconBtn.tag = i ;
        [iconBtn addTarget:self action:@selector(tapIconBtn:) forControlEvents:UIControlEventTouchUpInside];
        [shareShowView addSubview:iconBtn];
    }
    iconNamesArray = nil;
    CFBridgingRelease(CFBridgingRetain(iconNamesArray));
}


#pragma mark  Click on the icons button
-(void)tapIconBtn:(UIButton*) iconBtn{
    NSInteger indexBtnTag = iconBtn.tag ;
    switch (indexBtnTag) {
        case 0:{
            NWWeChatAPI * weChatApi = [NWWeChatAPI initializeSimpleInterest];
            BOOL  isInitialize = [weChatApi detectionInstallWeiChat];
            if (!isInitialize) {
                return ;
            }
            if (![weChatApi isWXAppSupportApi]) {
                return ;
            }
            weChatApi.shareImageData = UIImagePNGRepresentation([NWImageCompression getScreenshotsImage]);
            weChatApi.shareImageThumbData = UIImagePNGRepresentation([NWImageCompression getScreenshotsImage]);
            [weChatApi shareWeChatImage:NWWeiChatList];

        }
            break;
        case 1:{
            NWWeChatAPI * weChatApi = [NWWeChatAPI initializeSimpleInterest];
            BOOL  isInitialize = [weChatApi detectionInstallWeiChat];
            if (!isInitialize) {
                return ;
            }
            if (![weChatApi isWXAppSupportApi]) {
                return ;
            }
            weChatApi.shareImageData = UIImagePNGRepresentation([NWImageCompression getScreenshotsImage]);
            weChatApi.shareImageThumbData = UIImagePNGRepresentation([NWImageCompression imageCompressionRatioValue:0.1 withSourceImage:[NWImageCompression getScreenshotsImage]]);
            [weChatApi shareWeChatImage:NWWeiChatFrineds];


        }
            break;
        case 2:{
            NWQQShareAPI * QQApi = [NWQQShareAPI initializeSimpleInterest];
            BOOL  isInitialize = [QQApi detectionApplicationIsInstallation];
            if (!isInitialize) {
                return ;
            }
            if (![QQApi isQQSupportApi]) {
                return ;
            }
            QQApi.shareImageData = UIImagePNGRepresentation([NWImageCompression getScreenshotsImage]);
            QQApi.sharePreviewImageData = UIImagePNGRepresentation([NWImageCompression getScreenshotsImage]);
            [QQApi shareQQImage:NWQQList];
        }
            break;
        case 3:{

        }
            break;

        default:{
            return ;
        }
            break;
    }
}


#pragma mark   Popup layer clear theme
-(void)tapGestureMethod{
    /**
     获取现有的定时器,并清除
     */
    NSTimer * timer = (NSTimer*) objc_getAssociatedObject(self, @"Timer");
    [timer invalidate];
    [UIView animateWithDuration:0.5 delay:0.00 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
        shareShowView.frame = CGRectMake(0, CGRectGetHeight(self.frame),shareShowView.bounds.size.width, shareShowView.bounds.size.height);
        shareShowView.center = CGPointMake(self.center.x, shareShowView.center.y);
        shareShowView.alpha = 0.0 ;
    } completion:^(BOOL finished) {
        [shareShowView removeFromSuperview];
        CFBridgingRelease(CFBridgingRetain(shareShowView)) ;
        [self removeFromSuperview];
        CFBridgingRelease(CFBridgingRetain(self)) ;
    }];
}
@end

四、分享的效果图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zhoushuangjian511/article/details/75943347