手机截屏直接分享&反馈
Posted iOS的美丽岁月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手机截屏直接分享&反馈相关的知识,希望对你有一定的参考价值。
前言
目前市面上的一些主流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
四、分享的效果图
以上是关于手机截屏直接分享&反馈的主要内容,如果未能解决你的问题,请参考以下文章