项目中需要将网页生成长图并保存到本地或者分享的功能
废话不多说,这里上相关逻辑的代码:
由于网页并不一定只是一屏幕的高度,一般都是超出屏幕高度,这里就需要去判断增加高度.
// 生成长图
- (UIImage *)snapshotViewFromRect:(CGRect)rect withCapInsets:(UIEdgeInsets)capInsets {
CGFloat scale = [UIScreen mainScreen].scale;
CGSize boundsSize = self.web.bounds.size;
CGFloat boundsWidth = boundsSize.width;
CGFloat boundsHeight = boundsSize.height;
CGSize contentSize = self.web.scrollView.contentSize;
CGFloat contentHeight = contentSize.height;
CGFloat contentWidth = contentSize.width;
CGPoint offset = self.web.scrollView.contentOffset;
[self.web.scrollView setContentOffset:CGPointMake(0, 0)];
NSMutableArray *images = [NSMutableArray array];
while (contentHeight > 0) {
UIGraphicsBeginImageContextWithOptions(boundsSize, NO, [UIScreen mainScreen].scale);
// 在当前上下文中渲染出webView
// 如果取webView.scrollView.layer则会超出一屏的数据不能显示,只能显示白色区域块
[self.web.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[images addObject:image];
CGFloat offsetY = self.web.scrollView.contentOffset.y;
// 设置webView的偏移量
[self.web.scrollView setContentOffset:CGPointMake(0, offsetY + boundsHeight)];
contentHeight -= boundsHeight;
}
[self.web.scrollView setContentOffset:offset];
CGSize imageSize = CGSizeMake(contentSize.width * scale,
contentSize.height * scale);
UIGraphicsBeginImageContext(imageSize);
[images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) {
[image drawInRect:CGRectMake(0,
scale * boundsHeight * idx,
scale * boundsWidth,
scale * boundsHeight)];
}];
// 截取当前上下文生成Image
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *snapshotView = [[UIImageView alloc]initWithFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)];
snapshotView.image = [fullImage resizableImageWithCapInsets:capInsets];
return snapshotView.image;
}
生成长图之后分享图片:
这里是采用的友盟分享,分享图片并不是非得下载存储图片,
@property (nonatomic,strong) UIImage *shareImage; // 生成长图
// 图片分享
- (void)shareImageToPlatformType:(UMSocialPlatformType)platformType {
//创建分享消息对象
UMSocialMessageObject *messageObject = [UMSocialMessageObject messageObject];
//创建图片内容对象
UMShareImageObject *shareObject = [[UMShareImageObject alloc] init];
//如果有缩略图,则设置缩略图
// shareObject.thumbImage = [UIImage imageNamed:@"AppIcon"];
// 设置分享上图中的图片
[shareObject setShareImage:self.shareImage];
//分享消息对象设置分享内容对象
messageObject.shareObject = shareObject;
//调用分享接口
[[UMSocialManager defaultManager] shareToPlatform:platformType messageObject:messageObject currentViewController:self completion:^(id data, NSError *error) {
if (error) {
ZLLog(@"************Share fail with error %@*********",error);
}else{
ZLLog(@"response data is %@",data);
}
}];
}
生成长图之后也有需求是需要保存在本地:
- (void)screenshotPic {
CGRect snapshotFrame = CGRectMake(0, 0, _web.scrollView.contentSize.width, _web.scrollView.contentSize.height);
UIEdgeInsets snapshotEdgeInsets = UIEdgeInsetsZero;
UIImage *shareImage = [self snapshotViewFromRect:snapshotFrame withCapInsets:snapshotEdgeInsets];
self.shareImage = shareImage;
// 存储到相册
UIImageWriteToSavedPhotosAlbum(shareImage, self, nil, NULL);
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 延时0.7s
[MBProgressHUD showSuccess:@"已保存至相册"];
// });
}
这里一点击保存相册就发现闪退了。发现 Xcode 报以下错误:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
问题跟 iOS 10 保存图片、调用相机一样, Info.plist 里面要涉及隐私数据时要添加提示语。
打开 Info.plist,点击 + 号,在 Key 中输入:Privacy - Photo Library Additions Usage Description,Type 选择 String,Value 中输入你的提示语。
这是 iOS 11 新出的一条隐私规则,说明如下:
iOS11下,苹果对相册的权限key做了调整,原来NSPhotoLibraryUsageDescription,在iOS11之后,改成了NSPhotoLibraryAddUsageDescription
iOS 11 新增的隐私设置
iOS 11 中新加的还有一个跟 NFC 设备有关 NFCReaderUsageDescription,不过暂时没接触到。