iOS之图文混排
首先从github下载 https://github.com/wezm/RegexKitLite
导入.h和.m文件后为RegexKitLite.m添加编译标记-fno-objc-arc。添加动态库libicucore.dylib
UITextView *tv = [[UITextView alloc]init];
tv.x = 20;
tv.y = 200;
[self.view addSubview:tv];
1初始化一个属性字符串
NSString *text = @"https://www.baidu.com 今天发送了[笑cry]一件很有意思的事情[笑尿]。";
//2 指定匹配规则
// 表情的规则
NSString *emotionPattern = @"\\[[a-zA-Z\\u4e00-\\u9fa5]+\\]";
// @的规则
NSString *atPattern = @"@[0-9a-zA-Z\\u4e00-\\u9fa5-_]+";
// #话题#的规则
NSString *topicPattern = @"#[0-9a-zA-Z\\u4e00-\\u9fa5]+#";
// url链接的规则
NSString *urlPattern = @"[a-zA-z]+://[^\\s]*";
//3 对匹配到的范围进行高亮,只需要调用NSMutableAttributedString的addAttribute:::属性对特定范围的文字设置颜色属性。
NSString *pattern = [NSString stringWithFormat:@"%@|%@|%@|%@",atPattern,emotionPattern,topicPattern,urlPattern];
// 把[表情]替换成attachment图片,不能用replace和insert,因为会改变后面的相对位置,应该先拿到所有位置,最后再统一修改。
// 应该打散特殊部分和非特殊部分,然后拼接。
NSMutableArray *parts = [NSMutableArray array];
[text enumerateStringsMatchedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
if ((*capturedRanges).length == 0) return;
TextSegment *seg = [[TextSegment alloc] init];
seg.text = *capturedStrings;
seg.range = *capturedRanges;
seg.special = YES;
//判断是否是表情,表情的特点是有[ ]
seg.emotion = [seg.text hasPrefix:@"["] && [seg.text hasSuffix:@"]"];
[parts addObject:seg];
}];
[text enumerateStringsSeparatedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
if ((*capturedRanges).length == 0) return;
TextSegment *seg = [[TextSegment alloc] init];
seg.text = *capturedStrings;
seg.range = *capturedRanges;
seg.special = NO;
[parts addObject:seg];
}];
//通过上面的代码,我们把所有的文字部分都放入了parts数组中,为了拼接方便,我们应该按照位置的起始排序,从前到后依次拼接。
//这就需要对parts数组依据模型的range.location属性排序,比较常用的是根据block排序。
//block传入两个数组中的对象obj1、obj2,要求返回排序规则NSOrderedAscending、NSOrderedSame、NSOrderedDescending。
//NSOrderedAscending指的是obj1<obj2,系统默认按照升序排序,因此为了实现升序,发现obj1<obj2应该返回NSOrderedAscending。
[parts sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
TextSegment *ts1 = obj1;
TextSegment *ts2 = obj2;
// Descending指的是obj1>obj2
// Ascending指的是obj1<obj2
// 要实现升序,按照上面的规则返回。
// 系统默认按照升序排列。
if (ts1.range.location < ts2.range.location) {
return NSOrderedAscending;
}
return NSOrderedDescending;
}];
//接下来只需要从前到后拼接一个新创建的NSAttributedString,根据内容的不同拼接不同的内容。
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
//保存特殊文字
[self.specialSegments removeAllObjects];
NSInteger cnt = parts.count;
for (NSInteger i = 0; i < cnt; i++) {
TextSegment *ts = parts[i];
if (ts.isEmotion) {
NSTextAttachment *attach = [[NSTextAttachment alloc] init];
attach.image = [UIImage imageNamed:@"003"];
attach.bounds = CGRectMake(0, -3, 15, 15);
NSAttributedString *emotionStr = [NSAttributedString attributedStringWithAttachment:attach];
[attributedText appendAttributedString:emotionStr];
}else if(ts.isSpecial){
NSAttributedString *special = [[NSAttributedString alloc] initWithString:ts.text attributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
// 保存所有特殊文字的内容和位置,保存到模型,再把模型存入数组。
TextSpecial *spec = [[TextSpecial alloc] init];
spec.text = ts.text;
NSInteger loc = attributedText.length;
NSInteger len = ts.text.length;
spec.range = NSMakeRange(loc, len);
[self.specialSegments addObject:spec];
[attributedText appendAttributedString:special];
}else{
[attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:ts.text attributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}]];
}
}
//必须这是这个值,不然高度不够
[attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, attributedText.length)];
//然后调用boundingRectWithSize:计算尺寸,注意options必须选择options:NSStringDrawingUsesLineFragmentOrigin才能得到正确尺寸。
CGSize contentSize = [attributedText boundingRectWithSize:CGSizeMake(320, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
tv.size = contentSize;
tv.specialSegments = [self.specialSegments copy];
tv.attributedText = attributedText;
iOS之图文混排的更多相关文章
- ios开发--图文混排(富文本)
最近准备接一个编辑类的app,所以就查了下相关的功能,并自己试验了下: /** iOS 6之前:CoreText,纯C语言,极其蛋疼 iOS 6开始:NSAttributedString,简单易用 i ...
- iOS中 图文混排/自定义图文混排 作者:韩俊强
指示根视图:(准备几张图片,把label加载在window上) CustomLable *label = [[CustomLable alloc]initWithFrame:CGRectMake(0, ...
- iOS支持图文混排的按钮(UIButton)
创建UIButton子类 直接上代码了 .h文件 创建UIButton子类 直接上代码了 .h文件 #import <UIKit/UIKit.h> @interface GraphicBt ...
- iOS SDAutoLayout图文混排-共享
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #526eda } span.s1 { color: #4dbf5 ...
- ios图文混排
图文混排的形式 1. 富文本形式 2. core Text(文字排版) 3. TextKit 4. UIWebView 一.富文本 我们可以采用attributeString来进行图文混排.例如一个文 ...
- 【iOS】使用CoreText实现图文混排
iOS没有现成的支持图文混排的控件,而要用多个基础控件组合拼成图文混排这样复杂的排版,是件很苦逼的事情.对此的解决方案有使用CoreText进行绘制,或者使用TextKit.本文主要讲解对于CoreT ...
- 高性能图文混排框架,构架顺滑的iOS应用-b
About GallopGallop是一个功能强大.性能优秀的图文混排框架. Features主要用于解决以下需求: 滚动列表的性能优化.Gallop使用异步绘制.视图层级合并.观察mainRunlo ...
- IOS开发UI篇--一个支持图文混排的ActionSheet
一.简单介绍 UIActionSheet是IOS提供给我们开发人员的底部弹出菜单控件.一般用于菜单选择.操作确认.删除确认等功能.IOS官方提供的下面方式对UIActionView进行实例化: - ( ...
- iOS火焰动画效果、图文混排框架、StackView效果、偏好设置、底部手势等源码
iOS精选源码 高性能图文混排框架,构架顺滑的iOS应用. 使用OpenGLE覆盖阿尔法通道视频动画播放器视图. 可选最大日期截至当日日期的日期轮选器ChooseDatePicker 简单轻量的图片浏 ...
随机推荐
- 定时帧:NSTimer和CADisplayLink
学习参考了:http://www.jianshu.com/p/c35a81c3b9ebhttps://zsisme.gitbooks.io/ios-/content/chapter11/frame-t ...
- Web Service循序渐进学习
1.Web service 是什么? (WebService 是可以通过互联网远程访问调用的应用程序,实现数据传输共享.这种应用程序理解为不同服务提供帮助.能够支撑实现应用程序发布访问的技术可以称为W ...
- 每个Web开发者必备的9个软技能
对于一份工作,你可能专注于修炼自己的内功,会在不自觉中忽视软技能.硬技能决定你是否能得到工作,而软技能能够表明你是否适合这份工作和适应工作环境等.所有的公司都有属于自己的文化,并努力将这些文化传承下去 ...
- input 和raw_input
---恢复内容开始--- 因为看python2 和 3 混了,所以两者里面的东西有点乱input 和raw_input 今天终于搞明白了,在这里记录一下: 1.python 2 中raw_input ...
- hdu1008
//c++// #includeusing namespace std;int main(){int n,j,t,start;while (cin >> n,n){start =0;t = ...
- mvn 如何添加本地jar包 IDEA pom.xm
-------------背景介绍------------------------------------ 最近做的项目,就是office在线浏览功能, 使用的是openoffice+jodconve ...
- 【Sort】希尔排序
希尔排序(ShellSort),缩小增量排序,使用希尔增量时最坏运行时间O(n^2),不同的增量会对运行时间产生显著影响. void shellsort(int *nums,int n) { int ...
- hdu_5965_扫雷(递推)
题目链接:hdu_5965_扫雷 题意: 中文,还是自己看吧. 题解: 现场赛这题用的状压DP过的,不过现在想想当时还确实想复杂了,冷静下来仔细思靠一下,其实第i-1个确定了,那么第i个也是确定的,可 ...
- gdb常用调试命令
一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2.可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式) ...
- 【转】ActiveMQ与虚拟通道
郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436 ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个 ...