资讯专栏INFORMATION COLUMN

[分享]iOS开发-50行代码实现图文混排

yy13818512006 / 727人阅读

摘要:图文混排在这两块中使用最为常见,我已经做好了图文混排。文中会讲述几点小技巧图文混排动态计算文字长度图片拉伸方法。

开头
本文是技术集中的第一篇技术性文章,所以就记录一点简单且浅显易懂的东西。

现在即时通讯和朋友圈这两块功能基本上属于app的标配功能了吧。图文混排在这两块中使用最为常见,我已经做好了demo:图文混排demohttps://github.com/Joker-King...。

文中会讲述几点小技巧:图文混排动态计算文字长度图片拉伸方法


以前的做法

在以前做图文混排的时候,经常使用OHAttributedLabel,后来苹果吸取了一些第三方的优点,对NSString做了扩展,作者也不再更新,推荐用系统的方法来实现图文混排。具体请自行百度或者google关键字OHAttributedLabel。

现在的做法
苹果在iOS7中推出了一个新的类NSTextAttachment,它是做图文混排的利器,本文就是用这个类,只用50行代码实现文字与表情混排,当然也可以实现段落中的图文混排,与CoreText比起来实在是简单了太多,下面讲述两个案例。

案例一

先上效果图,聊天界面中的图文混排:

要实现这样的效果,code4app上似乎有很多种做法,还有一些奇葩的一个字符一个label,但是今天要讲述的做法,是目前为止我看到的最简单的做法了,只用一个UILabel,需要用到UILabel的attributedText属性。

首先,需要组装一个表情和文字对应的plist文件,plist中的键值对如下:

本文用一个工具类来实现一个转换的方法,你也可以给NSString添加一个类别来实现。

第一步,解析plist文件,转化为数组。

NSString*filePath = [[NSBundlemainBundle]pathForResource:@"emoticons"ofType:@"plist"];

NSArray*face = [NSArrayarrayWithContentsOfFile:filePath];

第二步,将字符串转换为可变属性字符串,并通过正则表达式匹配出所有的要替换的字符。
//1、创建一个可变的属性字符串

NSMutableAttributedString*attributeString = [[NSMutableAttributedStringalloc]initWithString:text];

//2、通过正则表达式来匹配字符串

NSString*regex_emoji =@"[[a-zA-Z0-9/u4e00-u9fa5]+]";//匹配表情

NSError*error =nil;

NSRegularExpression*re = [NSRegularExpressionregularExpressionWithPattern:regex_emojioptions:NSRegularExpressionCaseInsensitiveerror:&error];

if(!re) {

NSLog(@"%@", [errorlocalizedDescription]);

returnattributeString;

}

NSArray*resultArray = [rematchesInString:textoptions:0range:NSMakeRange(0, text.length)];

数组中都是NSTextCheckingResult对象,它包含了特殊字符在整个字符串中的位置等信息。

第三步,将特殊字符与对应表情关联

NSMutableArray*imageArray = [NSMutableArrayarrayWithCapacity:resultArray.count];

//根据匹配范围来用图片进行相应的替换

for(NSTextCheckingResult*matchinresultArray) {

//获取数组元素中得到range

NSRangerange = [matchrange];

//获取原字符串中对应的值

NSString*subStr = [textsubstringWithRange:range];

for(inti =0; i < face.count; i ++) {

if([face[i][@"cht"]isEqualToString:subStr]) {

//face[i][@"png"]就是我们要加载的图片

//新建文字附件来存放我们的图片,iOS7才新加的对象

NSTextAttachment*textAttachment = [[NSTextAttachmentalloc]init];

//给附件添加图片

textAttachment.image= [UIImageimageNamed:face[i][@"png"]];

//调整一下图片的位置,如果你的图片偏上或者偏下,调整一下bounds的y值即可

textAttachment.bounds=CGRectMake(0, -8, textAttachment.image.size.width, textAttachment.image.size.height);

//把附件转换成可变字符串,用于替换掉源字符串中的表情文字

NSAttributedString*imageStr = [NSAttributedStringattributedStringWithAttachment:textAttachment];

//把图片和图片对应的位置存入字典中

NSMutableDictionary*imageDic = [NSMutableDictionarydictionaryWithCapacity:2];

[imageDicsetObject:imageStrforKey:@"image"];

[imageDicsetObject:[NSValuevalueWithRange:range]forKey:@"range"];

//把字典存入数组中

[imageArrayaddObject:imageDic];

}

}

}

第四步,将特殊字符替换成图片

//4、从后往前替换,否则会引起位置问题

for(inti = (int)imageArray.count-1; i >=0; i--) {

NSRangerange;

[imageArray[i][@"range"]getValue:&range];

//进行替换

[attributeStringreplaceCharactersInRange:rangewithAttributedString:imageArray[i][@"image"]];

}

用法:

NSString*content =@"文字加上表情[得意][酷][呲牙]";

NSMutableAttributedString *attrStr = [Utility emotionStrWithString:content];

_contentLabel.attributedText= attrStr;


案例二:
需要实现的效果:

有了上面的方法,这个效果更容易实现,只需要将某些图片给它设置一个固定的字符对应即可。

与以上方法主要不同点在于正则表达式:

//2、匹配字符串

NSError*error =nil;

NSRegularExpression*re = [NSRegularExpressionregularExpressionWithPattern:stringoptions:NSRegularExpressionCaseInsensitiveerror:&error];

if(!re) {

NSLog(@"%@", [errorlocalizedDescription]);

returnattributeString;

}

用法:

NSString*praiseStr =@"路人甲、路人乙";

NSString*praiseInfo = [NSStringstringWithFormat:@"<点赞> %@",praiseStr];

NSDictionary*attributesForAll =@{NSFontAttributeName:[UIFontsystemFontOfSize:14.0],NSForegroundColorAttributeName:[UIColorgrayColor]};

NSMutableAttributedString*attrStr = [UtilityexchangeString:@"<点赞>"withText:praiseInfoimageName:@"dynamic_love_blue"];

彩蛋
1、计算动态文字的长度

NSMutableAttributedString*content = [UtilityemotionStrWithString:_dynamic.text];

[contentaddAttribute:NSFontAttributeNamevalue:kContentFontrange:NSMakeRange(0, content.length)];

CGSizemaxSize =CGSizeMake(kDynamicWidth,MAXFLOAT);

CGSizeattrStrSize = [contentboundingRectWithSize:maxSizeoptions:NSStringDrawingUsesLineFragmentOrigincontext:nil].size;

其中NSMutableAttributedString类型的字符串可以添加多种属性,并且在计算的时候必须设置字符大小等属性。

2、图片拉伸

在iOS5之前可以用stretchableImageWithLeftCapWidth: topCapHeight:

iOS5之中用resizableImageWithCapInsets:

iOS6开始多了一个参数resizableImageWithCapInsets:resizingMode:


分享来源:
http://www.jianshu.com/p/a8a4...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/16101.html

相关文章

  • iOS开发UI篇--一个支持图文混排的ActionSheet

    摘要:官方提供的以下方式对进行实例化从这个我们可以看出,我们只能设置文本标题,包括和,官方提供的该控件并不支持图文混排。但有的时候,交互提给我们的需求又需要我们的具有图文混排的效果,那就需要我们自己仿造系统自带的,完成该需求。 一、简介 UIActionSheet是IOS提供给我们开发者的底部弹出菜单控件,一般用于菜单选择、操作确认、删除确认等功能。IOS官方提供的以下方式对UIAction...

    jkyin 评论0 收藏0
  • iOS轻量富文本异步绘制框架

    摘要:前言如果遇到上面一个需求你会怎么处理若干个拼接我相信不论是哪种方式代码量都不小并且难以复用其他语言写富文本是那么轻松天生支持简单标签套标签而只要用过中的富文本都会觉得难用目前业界功能强大较为好用的是但设计思想是尽可能与相似所以相对使用也不是 前言 showImg(https://segmentfault.com/img/remote/1460000015424546?w=1484&h=...

    xiongzenghui 评论0 收藏0
  • 经验 - 收藏集 - 掘金

    摘要:实现的原理权限机制与适配经验掘金一概要已经发布一段时间了,市面上很多应用都已经适配。希望对大家有所帮助,更短信验证就是那么简单掘金又有半个月没更新文章了,最近工作比较忙,一时没时间写,今天趁着清闲,赶紧补上一篇。。。。。 2017,你绝对想尝试的新 Android 库 - Android - 掘金1 BufferTextInputLayout 直接看效果图:升序效果 ... 计算机程序...

    yimo 评论0 收藏0
  • 经验 - 收藏集 - 掘金

    摘要:实现的原理权限机制与适配经验掘金一概要已经发布一段时间了,市面上很多应用都已经适配。希望对大家有所帮助,更短信验证就是那么简单掘金又有半个月没更新文章了,最近工作比较忙,一时没时间写,今天趁着清闲,赶紧补上一篇。。。。。 2017,你绝对想尝试的新 Android 库 - Android - 掘金1 BufferTextInputLayout 直接看效果图:升序效果 ... 计算机程序...

    xiangchaobin 评论0 收藏0
  • 经验 - 收藏集 - 掘金

    摘要:实现的原理权限机制与适配经验掘金一概要已经发布一段时间了,市面上很多应用都已经适配。希望对大家有所帮助,更短信验证就是那么简单掘金又有半个月没更新文章了,最近工作比较忙,一时没时间写,今天趁着清闲,赶紧补上一篇。。。。。 2017,你绝对想尝试的新 Android 库 - Android - 掘金1 BufferTextInputLayout 直接看效果图:升序效果 ... 计算机程序...

    刘厚水 评论0 收藏0

发表评论

0条评论

阅读需要支付1元查看
<