您的位置:首页 > 其它

手机截屏直接分享&反馈

2017-07-23 17:49 447 查看

前言

目前市面上的一些主流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中都能实现触发该通知,我们就在 AppAppDelegate.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 导入到您的 [b]Project 里面。[/b]

第3步、 我们添加必要的支持库,如下图:



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



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



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

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



第7步 、 在我们检测到手势截屏的通知触发的方法里面植入 [b]ScreenshotsShareView 即可实现截屏分享。代码如下:[/b]

#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


四、分享的效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  截屏 分享功能