项目中需要将网页生成长图并保存到本地或者分享的功能
废话不多说,这里上相关逻辑的代码:
由于网页并不一定只是一屏幕的高度,一般都是超出屏幕高度,这里就需要去判断增加高度.
// 生成长图- (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,不过暂时没接触到。