我们在有些时候,因为性能和加载时间的问题,需要用UILabel加载html的方式来代替webview。
大部分情况,UILabel都可以很好的展示出想要的效果,但是却不能满足点击查看大图的需求。

本解决方式思路:获取图片的frame根据点击的point 判断是否属于图片

demo地址
https://github.com/msbaby520/MSHTMLImg

示例html代码

<p>这是第一张图片</p>
<p><img src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1563783041237&di=d0ed16a2df722fce876f82a4d5a45ce1&imgtype=0&src=http%3A%2F%2Fwww.pptbz.com%2Fupfile%2Fpptpic%2F201407%2F2014072815340215.jpg\" width=\"300\" ></p>
<p>这是第二张图片这是第二张图片这是第二张图片这是第二张图片这是第二张图片这是第二张图片这是第二张图片</p>
<p><img src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1563787705041&di=7708747caf3ee9da672ce4ce0848a60c&imgtype=0&src=http%3A%2F%2Fpic41.nipic.com%2F20140508%2F18609517_112216473140_2.jpg\" width=\"300\" ></p>

1、如何展示

NSMutableAttributedString *htmlStr = [[NSMutableAttributedString alloc] initWithData:[str dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];[htmlStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(0, htmlStr.length)];self.label.attributedText = htmlStr;

效果如下,我们可以通过添加attribute的方式进行其他修饰

通过调试我们会发现

\U0000fffc就是我们的图片占位符
NSAttachment就是我们的图片附件

此时直觉告诉我,获取到图片所在的 range 是至关重要的

2、如何获取图片的range

我们通过查看 NSAttributedString类,可以发现如下方法,可以帮助我们循环遍历属性字符串得到我们想要的attachment,及其对应的range

[htmlStr enumerateAttributesInRange:NSMakeRange(0, htmlStr.length) options:(NSAttributedStringEnumerationLongestEffectiveRangeNotRequired) usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {if ([attrs objectForKey:NSAttachmentAttributeName]) {// 获取图片附件所在的range}
}];

3、如何获取图片的Frame

在属性字符串中我们可以通过range获取frame,代码如下

// 通过图片附件的range获取图片相对于label的Frame
- (CGRect)boundingRectForCharacterRange:(NSRange)range{NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:htmlStr];NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];[textStorage addLayoutManager:layoutManager];NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:[self.label bounds].size];textContainer.lineFragmentPadding = 0;[layoutManager addTextContainer:textContainer];NSRange glyphRange;[layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];CGRect rect = [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];return rect;
}

4、对第2步进行代码整理

此时通过思考,我们大概知道要进行点击放大图片,需要知道两个条件,一个是image,另一个是frame,那我们就需要借助一个模型来完善代码。

 - (void)getImageModelsWithHtmlStr:(NSAttributedString *)htmlStr{__weak typeof(self) weakSelf = self;NSMutableArray *arr = [NSMutableArray array];[htmlStr enumerateAttributesInRange:NSMakeRange(0, htmlStr.length) options:(NSAttributedStringEnumerationLongestEffectiveRangeNotRequired) usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {if ([attrs objectForKey:NSAttachmentAttributeName]) {NSTextAttachment *attachement = [attrs objectForKey:NSAttachmentAttributeName];CGRect rect = [weakSelf boundingRectForCharacterRange:range];NSLog(@"===========%@",NSStringFromCGRect(rect));MSHTMLImgModel *model = [MSHTMLImgModel new];model.rect = rect;// 获取附件imagemodel.image = [UIImage imageWithData:attachement.fileWrapper.regularFileContents] ;[arr addObject:model];}if (range.location + range.length == htmlStr.length){weakSelf.arr = arr;}}];
}

5、判断点击事件,显示大图

  • 1、获取点击的点在label内的point
UIGestureRecognizer.h
-(CGPoint)locationInView:(nullable UIView*)view;
  • 2、判断point是否某个范围内
CG_EXTERN bool CGRectContainsPoint(CGRect rect, CGPoint point)
  • 3、整合代码
- (void)tapLabel:(UITapGestureRecognizer *)sender{CGPoint point = [sender locationInView:self];NSLog(@"handleSingleTap!pointx:%f,y:%f",point.x,point.y);MSHTMLImgModel *currentModel = nil;// 循环遍历数组进行判断for (MSHTMLImgModel *model in self.arr) {if (CGRectContainsPoint(model.rect, point)){currentModel = model;break;}else{continue;}}if (currentModel) {获取到了图片(currentModel.image)我们可以通过图片浏览器等进行点击查看大图操作。具体不在详述。}
}

6、优化

我们可能会在多个地方用到这个逻辑,我目前想到的方式是封装一个label。
demo地址
https://github.com/msbaby520/MSHTMLImg

iOS UILabel加载html点击图片查看大图 附demo相关推荐

  1. 基于JavaScript实现移动端点击图片查看大图点击大图隐藏

    今天找到了一个我用了很好的方法,点击缩略图,放大居中展示,且参数可调,亲测可靠. 代码使用意见,将下面的代码放到本地测试效果,可以用一张自己的照片,点击会放大,再次点击还原. 一.需求  点击图片查看 ...

  2. html点击小图标显示全屏查看大图,基于JavaScript实现移动端点击图片查看大图点击大图隐藏...

    一.需求 点击图片查看大图,再点大图隐藏.多用于移动端,因为移动端屏幕小,可能需要查看大图. 二.代码 JQuery点击图片查看大图by starof .exampleImg { height:100 ...

  3. php图片点击查看大图,基于JavaScript实现移动端点击图片查看大图点击大图隐藏_javascript技巧...

    一.需求 点击图片查看大图,再点大图隐藏.多用于移动端,因为移动端屏幕小,可能需要查看大图. 二.代码 JQuery点击图片查看大图by starof 三.技巧 因为移动端无法添加热点,最终一个解决方 ...

  4. HTML5点击图片查看大图,科技常识:HTML5 实现图片预览和查看原图

    今天小编跟大家讲解下有关HTML5 实现图片预览和查看原图 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了有关HTML5 实现图片预览和查看原图 的相关资料,希望小伙伴们看了有所帮助. htm ...

  5. IOS UITableView 加载未知宽高图片的解决方案

    在开发中遇到了UITableView列表 UITableViewCell装载图片但不知Image的宽高 问题. 在解决该问题的时候,首先想到的是异步加载图片 采用第三方框架SDWebImage 实现对 ...

  6. iOS中加载Flutter中的图片

    在 Flutter 插件开发中,有时需要将 Flutter 中配置的图片资源传递到 Android 或者是 iOS原生中,传递方法如下: //一般应用在Flutter 插件开发中 //注册插件的方法 ...

  7. iOS 动态加载LaunchScreen上的图片

    前言 hihi,勇敢的小伙伴儿们大家好,明天就要放元旦假期了,小长假三天你们准备去哪玩呢? 我就不出去玩了,买了一本新书在家攻读,如果有时间有机会的话我会写成博客跟大家一起分享. 今天分享的这个吧,恕 ...

  8. html多个图片成一个图,ios webview 加载HTML 多个图片URL 拼接成一张图片

    有head的HTML 1.拼接HTML 2.创建webview后  用这个方法加载HTML [self.webView loadHTMLString:[self reSizeImageWithHTML ...

  9. vue点击图片查看大图使用插件 vue-photo-preview

    1.引入插件 npm install vue-photo-preview --save 2.main.js import preview from 'vue-photo-preview'import ...

最新文章

  1. 对列表去重并保持原来的顺序
  2. 铅笔线的阻抗有多大?
  3. linux mysql 指令无效_linux下安装mysql,mysql命令失效的原因
  4. 前端学习(1044):本地存储实现数据录入
  5. [FWT] UOJ #310. 【UNR #2】黎明前的巧克力
  6. python绝对值函数fabs_Python fabs() 函数
  7. 控制QLineEdit的输入范围
  8. u3d打包成exe以及调试
  9. 计算机应用基础试卷分析报告,计算机应用基础试卷分析.pdf
  10. 2021-06-19
  11. RTF转HTML(<div>标签)格式的方法(java)
  12. 优秀工程师应该具备哪些素质_作为现代工程师应具备的素养
  13. 洪恩软件进军网游产业 池宇峰揭密完美世界
  14. Amazon alexa skill开发中遇到的坑
  15. GO 常见环境变量与常用命令
  16. 【Unity面试】 C#语言基础核心 | 面试真题 | 全面总结 | 建议收藏
  17. 短视频系统源代码,加载本地图片和加载网络图片
  18. Array,String 方法
  19. 今天,传说中的老方给我们班上课了
  20. PyQt5_股票技术图形查看工具

热门文章

  1. win10家庭版通过命令gpedit.msc打不开组策略的解决方法
  2. 程序编译是出现“field has incomplete type“问题的解决
  3. Java 创建用户异常类、将异常一直向上抛、 throw和throws的区别
  4. 在Java中使用final关键字可以提高性能吗?
  5. 在打印预览模式下使用Chrome的Element Inspector?
  6. poj 1950 Dessert(dfs枚举,模拟运算过程)
  7. dTree 动态生成树(http://luohua.iteye.com/blog/451453)
  8. memcached基本操作和语法
  9. android Fragments详解五:与activity通讯
  10. 界面-工作者线程结构之:异步委托调用