ios android 图文混排,[分享]iOS开发-50行代码实现图文混排
开头
本文是技术集中的第一篇技术性文章,所以就记录一点简单且浅显易懂的东西。
现在即时通讯和朋友圈这两块功能基本上属于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:
ios android 图文混排,[分享]iOS开发-50行代码实现图文混排相关推荐
- [分享]iOS开发 - 网络总结
基本概念 客户端:client 服务器:server 请求:request 响应:response 过程 客户端 -> 发送请求 -> 服务器(连接数据库) 服务器 -> 发送响应 ...
- [分享]iOS开发-UI篇:CAlayer层的属性
iOS开发UI篇-CAlayer层的属性 一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property ...
- [分享]iOS开发-实现view底部控件随着键盘的弹出而上移的效果
首先说一下思路: 想要达到底部控件随着键盘的弹出而上移的效果,那么我们必然需要的到键盘在弹出时的高度,以及原点坐标. 说白了我们的大致思路就是,用view的高度-键盘弹出时的高度,得到的值就是底部控件 ...
- [分享]iOS开发-如何使用tabBarController
由于难度不大,直接上代码了,看一遍基本就明白思路了 1.创建一个tabBarViewController .m文件 #import "SSTabBarViewController.h&quo ...
- [分享]iOS开发-实现UILabel显示出不同颜色并且某一部分产生下划线的效果 ...
效果图: @interface XSRecommendedPrivilegeViewController () @property (weak, nonatomic) IBOutlet UIButto ...
- IOS仿[自选股]项目开发
[自选股]手机客户端致力于通过先进的移动互联技术,让广大投资者尊享更便捷的证券投资服务.其简约易用 功能特点 一:界面简洁 登录人性化 用户可通过QQ账户登录软件,无需注册登录.登录后,软件会自动同步 ...
- 思科(Cisco)IOS 12.3特性分析[ZT]
cisco的ios 12.3和其子版本不仅包含增加的基本变化和漏洞修复.一起来近距离体验12个最有用的变化,包括网络准入控制(nac),最优边缘路由,动态多点***,ipsec全状态故障恢复等. 可能 ...
- Android 仿今日头条的视频播放控件(几行代码快速实现)
前段时间由于项目需要用到类似于今日头条的视频播放器,实现在线播放,边缓存边播放,当然也可以播放本地文件,如下图: 这里我推荐大家使用的是jiecaovideoplayer开源库,这个库的播放引擎是ij ...
- [IOS]iphone开发之常用代码:不断更新
1,获取翻转事件,并开启翻转: 只要在viewcontroller的类中加入 -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOri ...
- [转]iOS 远程推送(APNs)
我是搬运工.原帖:http://blog.csdn.net/lifengzhong/article/details/7737028 目录(?)[-] 一简介 二使用步骤 step1 step2 ste ...
最新文章
- ubuntu下安装wine
- 图书管理系统之外键的增删改查
- 20170728xlVBA改转置一例
- 各大媒体优劣对比_吉利星瑞特别版对比朗逸,亮点只有性价比?
- git tag 的基本用法
- MegaRAID Storage Manager RAID管理工具实用教程
- Page Cache与Page回写
- 华为手机备忘录的字体怎么调大?
- 度分秒换算题及答案C语言,度分换算(度分秒换算50题及答案)
- vcpkg安装库时异常解决
- 用spark中DataFrame对数据进行去重、缺失值处理、异常值处理
- 证件照处理:一寸照片换底色
- FTP服务报错227解决办法
- Oracle12C 基本操作和使用
- thinkpadt410接口介绍_thinkpad T410的扩展插口!
- AirDrop显示名字的修改问题
- CTFSHOW 萌新赛 萌新记忆
- 信号与系统 chapter7 因果与非因果
- 建立您自己的动画贺卡
- 【实例】用PHP制作一个简单的日历