美文网首页iOS开发iOS资料iOS
iOS UIWebView仿微信H5页面实现长按保存图片功能

iOS UIWebView仿微信H5页面实现长按保存图片功能

作者: Two_Seven | 来源:发表于2016-06-04 18:03 被阅读9803次
最终实现效果图

选择放这张效果图的时候很是忐忑啊,不知道会不会被和谐掉。

拿到需求之后分析了一下,其实主要功能点就是如何才能通过手指按压位置获取到相应的图片资源。是不是很抓狂,如果考虑到设备适配,谁知道手指按在什么地方了。

直接google查到了下面的这两行代码,然后跑到H5大哥那请教,给我实际演示了一下,发现能够完美解决上面的问题。

NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];

整篇文章的精髓就全在上面的那两行代码里了,接下来我就把完整的实现代码放上来。

首先是给UiWebView加一个长按手势。

UILongPressGestureRecognizer* longPressed = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];
longPressed.delegate = self;
[self.webView addGestureRecognizer:longPressed];

接着在手势响应方法里面实现相应的获取图片地址的方法,并弹出SheetView。这里需要注意的是一定要判断手势的state属性,想知道后果的同学可以注掉判断代码自己尝试一下。另外就是如果手指长按位置是非图片的话,urlToSave是一个nil值。

- (void)longPressed:(UILongPressGestureRecognizer*)recognizer
{
    if (recognizer.state != UIGestureRecognizerStateBegan) {
        return;
    }
    
    CGPoint touchPoint = [recognizer locationInView:self.webView];
    
    NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
    NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];
    
    if (urlToSave.length == 0) {
        return;
    }
    
    [self showImageOptionsWithUrl:urlToSave];
}

接下来的方法是调用一个自己封装好的SheetVIew,大家完全可以跳过,列出来只是为了不破坏代码的连贯性。

- (void)showImageOptionsWithUrl:(NSString *)imageUrl
{
    RAActionCustomButton *saveBtn = [[RAActionCustomButton alloc] init];
    saveBtn.type = kRAActionCustomButtonTypeSheetWhite;
    [saveBtn setTitle:@"保存图片" forState:UIControlStateNormal];
    saveBtn.touchUpInsideBlock = ^(RAActionCustomButton *btn){
        [self saveImageToDiskWithUrl:imageUrl];
    };
    
    RAActionCustomButton *cancelBtn = [[RAActionCustomButton alloc] init];
    cancelBtn.type = kRAActionCustomButtonTypeSheetWhite;
    [cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
    cancelBtn.touchUpInsideBlock = ^(RAActionCustomButton *btn){
        
    };
    
    RAActionSheet *sheet = [[RAActionSheet alloc] init];
    sheet.actionBtns = @[ saveBtn, cancelBtn];
    [sheet show];
}

最后就是请求图片并保存到相册的方法。这里需要注意一下cachePolicy这个参数,当前选择的参数含义是只有在cache中不存在data时才从原始地址下载。在实现过程中大家可以根据实际的功能需求来选择不同的参数。

- (void)saveImageToDiskWithUrl:(NSString *)imageUrl
{
    NSURL *url = [NSURL URLWithString:imageUrl];
    
    NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue new]];
    
    NSURLRequest *imgRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0];
    
    NSURLSessionDownloadTask  *task = [session downloadTaskWithRequest:imgRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            return ;
        }
        
        NSData * imageData = [NSData dataWithContentsOfURL:location];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            UIImage * image = [UIImage imageWithData:imageData];
            
            UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
        });   
    }];
    
    [task resume];
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        [[RAProgressHUD sharedHUD] showErrorWithMessage:@"保存失败"];
    }else{
        [[RAProgressHUD sharedHUD] showSuccessWithMessage:@"保存成功"];
    }
}

功能实现代码已经完整的贴出来了,接下来聊一些文章之外的事情。首先感谢大家对我的支持,尤其是上一篇文章iOS雷达图 iOS RadarChart实现,不过让人哭笑不得的是大家要demo的方式有一种向老司机要种子的既视感😂。没有及时放上demo是我偷懒了,我会马上更新的。另外要特别感谢给我打赏的那位,感谢你对我的认可,真是让我受宠若惊,我的文章竟然值钱咧。

再有就是我的文章都是在简书上面写的,所以大家有什么问题还是最好到原文章下面来讨论(尤其是要demo),不然我是看不到的,而且有些网站在转载的时候连排版都不会检查一下,真的很让人头疼。

如果你觉得这篇文章多多少少帮助到了你一些,打赏倒是不用,点个关注加喜欢吧,谢谢大家的认可。

相关文章

网友评论

  • 逸小苼:NSData * data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:imgUrl]];

    imageWithData

    UIImageWriteToSavedPhotosAlbum(webImage, nil, nil, nil);

    这样的话稳定不,
  • CoderRocker_Axl:老哥稳。
  • 魔法黛:我是看妹子才进来的:smiley:
  • 布袋的世界:偶可以说偶是看到图才认真看完全文的吗
  • 小鬼别多嘴:楼主故意放的这张图片,我知道
  • TitanCoder:前辈,求demo
  • e07603a18479:RAActionCustomButton是第三方的库吗?
    可否发一份源码给我 356660677@qq.com,谢谢!
  • iYeso:不错 copy过来直接用
  • 勿问情殇:有 demo 吗?想要
  • _我和你一样:http://mini.eastday.com/mobile/160926170514190.html?idx=11&recommendtype=-1&ishot=0&fr=lishi
    这里面的图片能抓到吗?使用WKWebView.(UIViewView存在严重的内存泄漏,且貌似不支持HTML5)
  • Twenty_:更新下文章吧。。 我因为没加这个代理。。这个ActionSheet 出现不稳定
  • treeDow:NSString *jsForTagName = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", touchPoint.x, touchPoint.y];
    NSString * tagName = [self.webView stringByEvaluatingJavaScriptFromString:jsForTagName];
    if (![tagName isEqualToString:@"img"] && ![tagName isEqualToString:@"IMG"]) {
    return;
    }
    我的项目里加上这些代码,保证长按的是图片
  • 香烟不灭:好东西,我喜欢加收藏。
  • Easy_VO:我今年有三十二场简书打赏,邀你参加:smile:
    Two_Seven:@Easyzhan 哈哈哈哈 原来是杨坤大哥 你好你好
    Easy_VO:@Two_Seven :stuck_out_tongue_winking_eye:简单的说就是图好文章好我为你转身~
    Two_Seven:@Easyzhan 没懂
  • 西木柚子:博主,能不能放个demo出来,谢谢
    Two_Seven:嗯嗯,对 ,是我的疏忽,由于我的这个方法写在基类里面了所以把它忘掉了,稍后我更新一些:relaxed: 谢啦
    西木柚子:@Two_Seven 额,不用了,弄好了。博主最好加原文的代码中加上如下代码。不然按照文章中的代码是无法实现长按手势的
    -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
    return YES;
    }
    Two_Seven:@西木柚子 今天有活,等我这两天我更新下哈
  • 下弦月丿:好评 :heart_eyes:
  • 乆丩乣:没必要忐忑 不会被和谐 http://www.jianshu.com/p/a9862d4dd94d
    97b0480a62d1:@乆_丩 装过头了,😂😂😂已被和谐😜😜
    Two_Seven:@乆_丩 哈哈哈哈哈
    乆丩乣:@乆_丩 我的是苍老师
  • 712dec607c53:冲着图片进来的,你赢了
  • 狗娃_::grin:图片好评,文章好评
    Two_Seven:@阿牛哥_ :smile:那以后效果图尽量都按这种来
  • csd_iosNewbird:棒棒哒
  • reloadRen:最后保存图片部分,可以用SDWebimage吗?似乎要简单点
    reloadRen:@reloadRen 噢噢,小白学习了,谢谢楼主
    Two_Seven:@reloadRen 其实webview是有自己的缓存的,所以如果用了sd之后可能就会又生成一份缓存:blush:
  • 28ed0a770375:不错
    a6d58425983d:能不能发个demo到我邮箱dohaeris@126.com,,很需要,谢谢!
  • 小微向前冲:我给你打赏评论之后,请教大神能否赏个雷达图的demo,迟迟未得到回复。
    小微向前冲:@Two_Seven 👌
    Two_Seven:@小微向前冲 已经更了小哥 :stuck_out_tongue_winking_eye: 今下午更的热乎乎滴 地址在原文章里
  • 北疆_:这个配图我给101分,因为我室友增加了又一个后宫成员变为101位。
    Two_Seven:@BabyFace老林 哈哈哈 强撸灰飞烟灭啊兄弟

本文标题:iOS UIWebView仿微信H5页面实现长按保存图片功能

本文链接:https://www.haomeiwen.com/subject/cxbldttx.html