手机截屏直接分享&反馈
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中都能实现触发该通知,我们就在 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 导入到您的 [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
四、分享的效果图
相关文章推荐
- 直接在屏幕上,选取区域进行截屏分享到QQ、微信
- “分享智能手机使用心得”新春茶话会·1月29日·北京·希格马中心
- 移动web端<input type="number">手机上点击直接打开数字键盘,并修改样式去除最右端上下箭头
- 分享一种系统事故&问题处理反馈方式(COE)
- android视频截屏&手机录屏实现
- Android使用adb命令对手机进行截屏保存到电脑&SDCard
- iOS Android 截屏分享图片,&& iOS自定义图片分享
- 手机直接分享链接到微信
- 手机截屏和图片分享
- eclipse 直接去手机中拖文件
- 微信开发之微信分享 node.js直接使用、C#、 java 通用
- 不用软件直接查询QQ好友的IP地址(二) && 通过 Ping 得知对方是否联网在线(与QQ是否上线无关)
- Android 获取浏览器当前分享页面的截屏
- 手机充电器拆解及RCC电路简要分析&amp;…
- 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
- 2014年主流手机对比(明天继续&hellip;&hellip;)
- 破解 VISTA & WIN7对直接磁盘写入的防护 win7 磁盘不可写 win7磁盘被写保护 win7磁盘写保护
- 用SqlClient连接方式时,w3wp直接报异常"Access Violation"
- iGrimaceV8 V8在线威锋源apt.so/qwkjv8手机直接下载安装教程