博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 图文混排
阅读量:6326 次
发布时间:2019-06-22

本文共 3621 字,大约阅读时间需要 12 分钟。

使用系统自带的NSAttributedString来处理,对于一般的图文混排已经足够了,但是,有一个缺点就是NSAttributedString并不支持gif动画。实际上,使用gif动画还是挺卡的。

思路:

1.通过RegexKitLite 正则,匹配出所有需要特殊处理的字符

2.由于表情图片占用一个字符,使用直接替换范围的方式,会导致后面的表情范围不对。有两种处理方案

方案一: 

  • 使用两个数组,分别装特殊字符(文字内容,文字范围,是否为特殊字符,是否为表情)和非特殊字符,按范围排序成一个新数组
  • 循环新数组List,通过判断是否为表情和是否为特殊字符来添加appendAttributedString属性。

方案二:

通过递归的方式,每找到一个表情,先替换掉,再递归找下一个

当前,使用的是方案一,核心代码:

/** *  普通文字 --> 属性文字 * *  @param text 普通文字 * *  @return 属性文字 */- (NSAttributedString *)attributedTextWithText:(NSString *)text{    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];        // 表情的规则    NSString *emotionPattern = @"\\[[0-9a-zA-Z\\u4e00-\\u9fa5]+\\]";    // @的规则    NSString *atPattern = @"@[0-9a-zA-Z\\u4e00-\\u9fa5-_]+";    // #话题#的规则    NSString *topicPattern = @"#[0-9a-zA-Z\\u4e00-\\u9fa5]+#";    // url链接的规则    NSString *urlPattern = @"\\b(([\\w-]+://?|www[.])[^\\s()<>]+(?:\\([\\w\\d]+\\)|([^[:punct:]\\s]|/)))";    NSString *pattern = [NSString stringWithFormat:@"%@|%@|%@|%@", emotionPattern, atPattern, topicPattern, urlPattern];        // 遍历所有的特殊字符串    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;                TextPartModel *part = [[TextPartModel alloc] init];        part.special = YES;        part.text = *capturedStrings;        part.emotion = [part.text hasPrefix:@"["] && [part.text hasSuffix:@"]"];        part.range = *capturedRanges;        [parts addObject:part];    }];        // 遍历所有的非特殊字符    [text enumerateStringsSeparatedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {        if ((*capturedRanges).length == 0) return;                TextPartModel *part = [[TextPartModel alloc] init];        part.text = *capturedStrings;        part.range = *capturedRanges;        [parts addObject:part];    }];        // 排序    // 系统是按照从小 -> 大的顺序排列对象    [parts sortUsingComparator:^NSComparisonResult(TextPartModel *part1, TextPartModel *part2) {        // NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending        // 返回NSOrderedSame:两个一样大        // NSOrderedAscending(升序):part2>part1        // NSOrderedDescending(降序):part1>part2        if (part1.range.location > part2.range.location) {            // part1>part2            // part1放后面, part2放前面            return NSOrderedDescending;        }        // part1
View Code

 在使用过程中,我们需要注意一点,计算文本的宽高,通过下面来计算

[status.attributedText boundingRectWithSize:CGSizeMake(maxW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

在计算过程中,我们并没有传字体大小,因而,我们需要给attributedText一开始设定字体大小:

// 一定要设置字体,保证计算出来的尺寸是正确的    [attributedText addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attributedText.length)];

设置行高

// 定义行高    NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];    [paragraphStyle setLineSpacing:5];    [attributedText addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedText.length)];

 

附源代码:

目录说明:

HomeViewController  ---列表

StatusCell       ---列表TableCell

StatusFrame       ---列表TableCell高度。由于cell的高度是不固定的,因此我们定义StatusFrame来管理所有的控件尺寸,最后返回总高度

StatusModel      ---微博模型,图文混排处理,在这里做核心混排处理,通过添加attributedText属性处理。

  --TextPartModel  --StatusModel嵌套属性,用于记录RegexKitLite 正则匹配出的字符

  --SpecialModel   --StatusModel嵌套属性,用于特殊实符点击变色的范围比比较

  --UserModel     --StatusModel嵌套属性,用户模型

 

转载地址:http://qmgaa.baihongyu.com/

你可能感兴趣的文章
二分查找中的对半查找和采用斐波那契法查找的效率分析(信息论描述)
查看>>
我对git的认识
查看>>
BZOJ2425:[HAOI2010]计数(数位DP)
查看>>
CLR读书笔记--第四章 类型基础
查看>>
CSS3实战开发 表单发光特效实战开发
查看>>
初识Ajax---简单的Ajax应用实例
查看>>
js 去除字符串空白符
查看>>
201521123026《JAVA程序设计》第13周学习总结
查看>>
【SICP练习】82 练习2.54
查看>>
[APUE]标准IO库(下)
查看>>
iOS - OC - 打印信息 - xcode 中文打印
查看>>
HDU - 4810 - Wall Painting (位运算 + 数学)
查看>>
05LaTeX学习系列之---TeX的命令行操作
查看>>
响应式设计中的响应式图片制作
查看>>
RequireJS使用小结1——for Effective JavaScript Module Loading
查看>>
【转载】NULL,"",String.Empty三者在C#中的区别
查看>>
05-使用jQuery操作input的value值
查看>>
学号 2017-2018-20172309 《程序设计与数据结构》第7周学习总结
查看>>
[转载]CentOS 6.3安装Subversion服务器
查看>>
详解PHP使用DOMDocument类遍历、增加、修改、删除XML节点操作
查看>>