开头
作为技术文章的首篇,本文旨在分享一些简单却实用的技术技巧。随着即时通讯和社交媒体的普及,图文混排已成为应用开发中常见的功能之一。本文将从图文混排的实现方法谈起,分享一些实用的实现技巧。
以前的做法
在过去的开发过程中,常用
OHAttributedLabel
来实现图文混排。然而,随着苹果对第三方库的整合和优化,系统级的NSString
扩展已成为更优的选择。如果你对OHAttributedLabel
感兴趣,可以通过搜索引擎了解更多信息。现在的做法
iOS7版本引入了新的
NSTextAttachment
类,这是一个极大便利的工具。通过这个类,我们可以轻松实现图文混排,甚至比CoreText
实现起来更简单。本文将通过两个实际案例,展示如何利用NSTextAttachment
实现图文混排。案例一
以下是一个典型的聊天界面中的图文混排效果:
实现这个效果的关键在于使用
UILabel
的attributedText
属性。我们需要一个表情与文字对应的plist文件,其结构如下:通过工具类或为
NSString
添加类别,我们可以将字符串中的特殊字符替换为图片。以下是具体实现步骤:NSString *filePath = [[NSBundle mainBundle] pathForResource:@"emoticons" ofType:@"plist"];NSArray *face = [NSArray arrayWithContentsOfFile:filePath];
// 2、创建可变属性字符串并匹配表情NSString *regex_emoji = @"\\[[a-zA-Z0-9\\/\\u4e00-\\u9fa5]+\\]";NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:regex_emoji options:NSRegularExpressionCaseInsensitive error:nil];if (!re) { NSLog(@"%@", [error localizedDescription]); return attributeString;}NSArray *resultArray = [re matchesInString:text options:0 range:NSMakeRange(0, text.length)];
// 3、关联表情和图片NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count];for (NSTextCheckingResult *match in resultArray) { NSValueRange.range = [match range]; for (int i = 0; i < face.count; i++) { if ([face[i][@"cht"] isEqualToString:subStr]) { NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; textAttachment.image = [UIImage imageNamed:face[i][@"png"]]; textAttachment.bounds = CGRectMake(0, -8, textAttachment.image.size.width, textAttachment.image.size.height); NSAttributedString *imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment]; NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2]; [imageDic setObject:imageStr forKey:@"image"]; [imageDic setObject:[[NSValueValueWithRange:range] forKey:@"range"]; [imageArray addObject:imageDic]; } }}
// 4、从后往前替换for (int i = (int)imageArray.count - 1; i >= 0; i--) { NSRange range; [imageArray[i][@"range"] getValue:&range]; [attributeString replaceCharactersInRange:range withAttributedString:imageArray[i][@"image"]];}
用法示例:
NSString *content = @"文字加上表情[得意][酷][呲牙]";NSMutableAttributedString *attrStr = [Utility emotionStrWithString:content];_contentLabel.attributedText = attrStr;
案例二
以下是一个更复杂的图文混排效果:
实现这个效果的关键在于正则表达式的灵活性。具体步骤与案例一类似,只是正则表达式的匹配规则有所不同:
NSString *praiseStr = @"路人甲、路人乙";NSString *praiseInfo = [NSString stringWithFormat:@" <点赞> %@", praiseStr];NSDictionary *attributesForAll = @{NSFontAttributeName:[UIFont systemFontOfSize:14.0], NSForegroundColorAttributeName:[UIColor grayColor]};NSMutableAttributedString *attrStr = [Utility exchangeString:@" <点赞> " withText:praiseInfo imageName:@"dynamic_love_blue"]; 点赞> 点赞>
彩蛋
1、动态计算文字长度
NSMutableAttributedString *content = [Utility emotionStrWithString:_dynamic.text];[content addAttribute:NSFontAttributeName value:kContentFont range:NSMakeRange(0, content.length)];CGSize maxSize = CGSizeMake(kDynamicWidth, MAXFLOAT);CGSize attrStrSize = [content boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
2、图片拉伸
iOS5及以上版本中,可以使用以下方法进行图片拉伸:
iOS5: UILabel *stretchedLabel = [[UILabel alloc] init];stretchedLabel.image = [UIImage stretchableImageWithLeftCapWidth:10 topCapHeight:15];
iOS6及以上版本: UILabel *resizableLabel = [[UILabel alloc] init];resizableLabel.image = [UIImage resizableImageWithCapInsets: UIEdgeInsetsMake(5, 10, 5, 10)];
iOS7及以上版本: UILabel *resizableLabel = [[UILabel alloc] init];resizableLabel.image = [UIImage resizableImageWithCapInsets: UIEdgeInsetsMake(5, 10, 5, 10) resizingMode:UIResizingModeScale];