最近开发需求遇到一个比较简单但又棘手的问题。先看需求
一个UILabel显示不同大小颜色的字符串,当然我们首先的想到属性字符串,但是注意:我们这里要处理国际化完成的字符串也就是说:
必须在国际化完成以后才能追加我们的逻辑,而不是一上来就加属性字符串
比如:2分14秒或2 min14secs
也就是给我们的是一个“2分14秒”字符串我们需要匹配范围来修改或者替换。带着这个疑问开始今天的文章& # 63;
孔圣贤有云:“举一隅不以三隅反,则不复也。”
出自《论语·第七章·述而篇》
引用>
为了不愧对圣贤对我的期待我把这个问题定位升级成4个等级
<李>一级最优解,时间复杂度最低,效率最高李> <李>二级非最优解,时间复杂度最低,效率高李> <李>三级都一般李> <李>四级简单粗暴李>
我想到了以下至少两种方法
<李>通过计算出来的时间,分秒字符串范围去国际化处理完的字符串去匹配修改李> <李>用正则匹配数字李> <李>用谓词匹配数字李> <李> level4太业余了不敢想向一个工作好几年的开发者还写出这么打脸的代码李>
在工程中拖拽了一个标签
@ interface ViewController () @ property(弱,原子)IBOutlet UILabel *标签; @end @ implementation ViewController - (void) viewDidLoad { (超级viewDidLoad);//调用 NSAttributedString * resultTime=(自我formattedCurrentTime: 133); self.label。attributedText=resultTime; }<强>方案1:字符串范围匹配强>
/* * 返回当前时间格式 @return返回组装好的字符串 */?NSAttributedString *) formattedCurrentTime:(NSTimeInterval) timeInterval { 了NSUInteger时间=(了NSUInteger) timeInterval; NSInteger分钟=(时间/60)% 60; NSInteger % 60秒=时间; NSString * minStr=[NSString stringWithFormat: @ % zd,分钟); NSString * secStr=[NSString stringWithFormat: @ % zd,秒);//假设这就是我们国际化后的字符串 NSString * localizedFormatString=[NSString stringWithFormat: @ % @分% @秒,minStr, secStr); NSMutableAttributedString * attributeStr=[[NSMutableAttributedString alloc] initWithString localizedFormatString):; NSRange minRange secRange; 如果(@available (iOS 9.0 *)) { minRange=[localizedFormatString localizedStandardRangeOfString minStr):; secRange=[localizedFormatString localizedStandardRangeOfString secStr):; 其他}{ minRange=[localizedFormatString rangeOfString minStr):; secRange=[localizedFormatString rangeOfString secStr):; } NSDictionary * timeAttrs=@ {NSForegroundColorAttributeName:(用户界面颜色redColor), NSFontAttributeName:(UIFont systemFontOfSize: 40.0 f]}; [attributeStr addattribute: timeAttrs范围:minRange]; [attributeStr addattribute: timeAttrs范围:secRange]; 返回[[NSAttributedString alloc] initWithAttributedString attributeStr):;; }看下显示结果
是不是看上去很好
但我认为这并不完的美,这种搞法虽然简单直接,但是过于依赖minStr和secStr的原始,基于iOS9之后提供的API计算范围
如果(@available (iOS 9.0 *)) { minRange=[localizedFormatString localizedStandardRangeOfString minStr):; secRange=[localizedFormatString localizedStandardRangeOfString secStr):; 其他}{ minRange=[localizedFormatString rangeOfString minStr):; secRange=[localizedFormatString rangeOfString secStr):; }API平台区分
但是这么实现有个虫子当遇到同样字符串的时候就会匹配错位,如图
错误的原因显然大家都了解
字符串“0”的范围相同了,但就解决这个问题而言,简单判断一范围下然后截取字符串向后跳跃长度继续截取获取能实现,但这显然很啰嗦,万一有一天你遇到的是“0小时0分12秒”这种字符串那该如何写呢?
iOS利用NSAttributeString实现不同颜色大小显示的方法