iOS 图文混排 链接 可点击
2016-01-13 15:36
337 查看
对于这个话题 我想到
1 第一个解决方法就是使用 webView 比较经典
把所有复杂工作都交给控件本身去处理了, 但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实现 也比较复杂,而且 这个需要对 html编码进行分析理解剥离等)
2 富文本方式 核心框架 coretext
图文混排 一点问题都没有 关键是怎么对 目标图片 或者链接 进行触发响应
要点:
(1)首先要封装的要相对独立 拓展也方便 首当其冲就是 和服务端约定的 数据模型 CoreTextModel 要敲定:
我们约定是 一段文字中间用 "[1]" 做标记 [我是图片id] ,同时传一个图片 和相应描述文字 "图片数组" 图片数组元素中主键就是这个图片id . 使用正则 去组织 CoreTextModel 数组集合
我们开发过程中是默认一张图片 点击这个图 展示解释 所以 直接知道这张图片大小 进行绘制, 如果是网络图片 那么就应该预留这张图片的大小 因为 绘制如果 不知道大小 线性绘制过程 就会卡在这 如果预知大小 那么就会继续往下绘制, 变成异步的
所以图片大小(宽高) 当然 也是这个图片数组元素 作为数据模型中的.属性元素而存在
如果是链接呢?? 所以 [1] 也可以认为是 [我是链接的id] 然后模型中有个参数 区分 当前 需要插入的是图片 还是 链接 或者其他需求 然后进行枚举判断
那么有几种枚举 就要有几个数据结构 比如这里 就有coreTextImageData && coreTextLinkData 和 绘制的过程 就需要 有几种可变数组 枚举的过程 分别进行add
(2)其次 绘制
首先来说 绘制 就是 直接动用底层CoreText
绘制图片\链接 都是动用底层 我现在的能力 是 调用\理解\修改\拓展 还不能自如的 写任意 自己想写东西 我想 也许当我到了这种程度 才能成为 大神吧 哈哈 路漫漫修远兮 吾将上下求索
1,遍历数据模型 CoreTextModel 数组 对 文本 夹杂"[1]"的重新组织
2,最终得到的富文本NSMutableAttributedString *result 都会通过 result.length 知道当前的图片/链接coreTextImageData/ coreTextLinkData的起始位置.
3,绘制 draw
a,绘制图片 (1)CTRunDelegateCallbacks callbacks;创建内存存储空间(怎么使用 百度 一大堆) (2) 使用0xFFFC作为空白的占位符 拼入 add 在result里
b,绘制链接 或者是一段连续子串 触发 给他指定颜色 下划线 大小等 同样 也add在result里
c,最终得到的 result 通过 创建CTFramesetterRef实例 获得 获得要缓制的区域的高度 再将生成好的CTFrameRef实例
ctFrame 和计算好的缓制高度height保存到CoreTextData实例中,最后返回CoreTextData实例(CoreTextData 这个结构体里面至少有ctFrame,height,result, coreTextImageData , coreTextLinkData )
ctFrame 这个 相当于 OC中 的 CGFrame , 但是成镜像且上下颠倒
盗个图:
CGFrame
Core Text CTFrameRef
所以如果触发点击事件 那么 还需要把这个绘制坐标 转成UI坐标
4,那么 现在 得到的result
在指定点击的UIView 要使用iPhone重绘机制drawRect 触发方法[self setNeedsDisplay] 调用- (void)drawRect:(CGRect)rect
就可展示出 这个视图了.
(4)触发点击事件
原理: 触发点击UIView 通过 UIGestureRecognizer * tapRecognizer.
点击事件中 可以获得 CGPoint point = [recognizer locationInView:self]; 点击焦点 . 那么 判断 这个 点击焦点 是不是 图 或者 是不是可触发的链接 或者字符串 就可以了
a,遍历 self.data.imageArray 判断 是否存在满足条件 如果满足 则 用 通知post 去触发点击响应
我使用了一个参数 focusRect 把焦点区域放大 一圈 防止 图片 太小点击 不上 这个是我开发过程中 需要也是必要的 大家用不用 看心情
链接 就举一反三吧 网上讲解也一大堆 目的达到了
好的链接参考
http://blog.csdn.net/sinat_27706697/article/details/46286717 http://blog.csdn.net/sinat_27706697/article/details/46299953 http://ju.outofmemory.cn/entry/53649 https://github.com/kobe1941/HFCoreTextDemo
//唐 https://github.com/tangqiaoboy/iOS-Pro
下一篇 接着讲 触发弹出 一个对话框的逻辑
1 第一个解决方法就是使用 webView 比较经典
把所有复杂工作都交给控件本身去处理了, 但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实现 也比较复杂,而且 这个需要对 html编码进行分析理解剥离等)
2 富文本方式 核心框架 coretext
图文混排 一点问题都没有 关键是怎么对 目标图片 或者链接 进行触发响应
要点:
(1)首先要封装的要相对独立 拓展也方便 首当其冲就是 和服务端约定的 数据模型 CoreTextModel 要敲定:
我们约定是 一段文字中间用 "[1]" 做标记 [我是图片id] ,同时传一个图片 和相应描述文字 "图片数组" 图片数组元素中主键就是这个图片id . 使用正则 去组织 CoreTextModel 数组集合
我们开发过程中是默认一张图片 点击这个图 展示解释 所以 直接知道这张图片大小 进行绘制, 如果是网络图片 那么就应该预留这张图片的大小 因为 绘制如果 不知道大小 线性绘制过程 就会卡在这 如果预知大小 那么就会继续往下绘制, 变成异步的
所以图片大小(宽高) 当然 也是这个图片数组元素 作为数据模型中的.属性元素而存在
如果是链接呢?? 所以 [1] 也可以认为是 [我是链接的id] 然后模型中有个参数 区分 当前 需要插入的是图片 还是 链接 或者其他需求 然后进行枚举判断
那么有几种枚举 就要有几个数据结构 比如这里 就有coreTextImageData && coreTextLinkData 和 绘制的过程 就需要 有几种可变数组 枚举的过程 分别进行add
(2)其次 绘制
首先来说 绘制 就是 直接动用底层CoreText
绘制图片\链接 都是动用底层 我现在的能力 是 调用\理解\修改\拓展 还不能自如的 写任意 自己想写东西 我想 也许当我到了这种程度 才能成为 大神吧 哈哈 路漫漫修远兮 吾将上下求索
1,遍历数据模型 CoreTextModel 数组 对 文本 夹杂"[1]"的重新组织
2,最终得到的富文本NSMutableAttributedString *result 都会通过 result.length 知道当前的图片/链接coreTextImageData/ coreTextLinkData的起始位置.
3,绘制 draw
a,绘制图片 (1)CTRunDelegateCallbacks callbacks;创建内存存储空间(怎么使用 百度 一大堆) (2) 使用0xFFFC作为空白的占位符 拼入 add 在result里
b,绘制链接 或者是一段连续子串 触发 给他指定颜色 下划线 大小等 同样 也add在result里
c,最终得到的 result 通过 创建CTFramesetterRef实例 获得 获得要缓制的区域的高度 再将生成好的CTFrameRef实例
ctFrame 和计算好的缓制高度height保存到CoreTextData实例中,最后返回CoreTextData实例(CoreTextData 这个结构体里面至少有ctFrame,height,result, coreTextImageData , coreTextLinkData )
ctFrame 这个 相当于 OC中 的 CGFrame , 但是成镜像且上下颠倒
盗个图:
CGFrame
Core Text CTFrameRef
所以如果触发点击事件 那么 还需要把这个绘制坐标 转成UI坐标
4,那么 现在 得到的result
在指定点击的UIView 要使用iPhone重绘机制drawRect 触发方法[self setNeedsDisplay] 调用- (void)drawRect:(CGRect)rect
就可展示出 这个视图了.
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; if (self.data == nil) {//self.data 是 CoreTextData return; } CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetTextMatrix(context, CGAffineTransformIdentity); CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); CTFrameDraw(self.data.ctFrame, context); //对所有指定位置的图片填充 for (CoreTextImageData * imageData in self.data.imageArray) { UIImage *image = [UIImage imageNamed:imageData.name]; if (image) { CGContextDrawImage(context, imageData.imagePosition, image.CGImage); } } }
(4)触发点击事件
原理: 触发点击UIView 通过 UIGestureRecognizer * tapRecognizer.
点击事件中 可以获得 CGPoint point = [recognizer locationInView:self]; 点击焦点 . 那么 判断 这个 点击焦点 是不是 图 或者 是不是可触发的链接 或者字符串 就可以了
a,遍历 self.data.imageArray 判断 是否存在满足条件 如果满足 则 用 通知post 去触发点击响应
我使用了一个参数 focusRect 把焦点区域放大 一圈 防止 图片 太小点击 不上 这个是我开发过程中 需要也是必要的 大家用不用 看心情
链接 就举一反三吧 网上讲解也一大堆 目的达到了
好的链接参考
http://blog.csdn.net/sinat_27706697/article/details/46286717 http://blog.csdn.net/sinat_27706697/article/details/46299953 http://ju.outofmemory.cn/entry/53649 https://github.com/kobe1941/HFCoreTextDemo
//唐 https://github.com/tangqiaoboy/iOS-Pro
下一篇 接着讲 触发弹出 一个对话框的逻辑
相关文章推荐
- iOS开发笔记--基于面向协议MVP模式下的软件设计
- iOS 字体加粗
- Git忽略规则及.gitignore规则不生效的解决办法
- 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?
- iOS(五)基于XMPP的聊天:一
- iOS开发多线程篇—GCD介绍
- 华为服务器RH5885 V3进入BIOS
- iOS个人整理08-touch触摸事件和手势识别器
- iOS-OC复合语句
- iOS开发教程之线程关于多线程的简单介绍
- cannot do a partial commit during a merge.
- IOS应用开发版本控制工具之Versions 和SVN 的 使用方法详解
- iOS项目的完整重命名方法图文教程
- iOS下载图片之SDWebImage的研究与使用
- iOS类似支付宝首页Item项的移动排序
- 录制视频的大Bug (IOS 不能播放)
- iOS及Mac开源项目和学习资料【超级全面】
- iOS开发之多工程联编
- iOS:创建静态库及其使用
- 使用nagios监控HP服务器RAID