说明:
本文通过类目为NSAttributedString添加两个新的方法, 实现基于正则表达式的简单图文混排
根据这两个方法封装一个现实图文混排的MixLabel
注: 本文由@河马流星锤编写, 转载请注明出处和作者
使用效果图
核心方法
类: NSMutableAttributedString
/** 传入参数为NSString, 返回黑色的字和图片 */
+ (NSMutableAttributedString *)emojiAttributedString:(NSString *)string withFont:(UIFont *)font;
/** 传入参数为NSMutableAttributedString, 返回与图片相同颜色的字和图片 */
+ (NSMutableAttributedString *)eemojiAttributedString:(NSMutableAttributedString *)string withFont:(UIFont *)font;
代码
+ (NSMutableAttributedString *)emojiAttributedString:(NSString *)string withFont:(UIFont *)font
{
/* 把参数NSString 变成 NSMutableAttributedString */
NSMutableAttributedString *parsedOutput = [[NSMutableAttributedString alloc]initWithString:string attributes:@{NSFontAttributeName : font}];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[[A-Za-z0-9]*\\]" options:0 error:nil];
NSArray* matches = [regex matchesInString:[parsedOutput string]
options:NSMatchingWithoutAnchoringBounds
range:NSMakeRange(0, parsedOutput.length)];
/* 找到plist文件 */
NSDictionary *emojiPlistDic = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Emoji" ofType:@"plist"]];
/* 设置表情和字大小的对比尺寸 */
CGSize emojiSize = CGSizeMake(font.lineHeight, font.lineHeight);
for (NSTextCheckingResult* result in [matches reverseObjectEnumerator]) {
NSRange matchRange = [result range];
/* 通过占位的字符找到表情图片 */
NSString *placeholder = [parsedOutput.string substringWithRange:matchRange];
UIImage *emojiImage = [UIImage imageNamed:emojiPlistDic[placeholder]];
/* 根据上面设置大图片大小调整图片尺寸 */
UIGraphicsBeginImageContextWithOptions(emojiSize, NO, 0.0);
[emojiImage drawInRect:CGRectMake(0, 0, emojiSize.width, emojiSize.height)];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSTextAttachment *textAttachment = [NSTextAttachment new];
textAttachment.image = resizedImage;
/* 用图片替换掉占位符 */
NSAttributedString *rep = [NSAttributedString attributedStringWithAttachment:textAttachment];
[parsedOutput replaceCharactersInRange:matchRange withAttributedString:rep];
}
return [[NSMutableAttributedString alloc]initWithAttributedString:parsedOutput];
}
/* 直接使用传入的 NSMutableAttributedString可以设置字体的颜色和图片颜色一致 */
+ (NSMutableAttributedString *)eemojiAttributedString:(NSMutableAttributedString *)string withFont:(UIFont *)font {
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[[A-Za-z0-9]*\\]" options:0 error:nil];
NSArray* matches = [regex matchesInString:string.string
options:NSMatchingWithoutAnchoringBounds
range:NSMakeRange(0, string.length)];
NSDictionary *emojiPlistDic = [[NSDictionary alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Emoji" ofType:@"plist"]];
/* Make emoji the same size as text */
CGSize emojiSize = CGSizeMake(font.lineHeight - 3, font.lineHeight - 5);
NSLog(@"%f", font.lineHeight);
for (NSTextCheckingResult* result in [matches reverseObjectEnumerator]) {
NSRange matchRange = [result range];
/* Find emoji images by placeholder */
NSString *placeholder = [string.string substringWithRange:matchRange];
UIImage *emojiImage = [UIImage imageNamed:emojiPlistDic[placeholder]];
/* Resize Emoji Image */
UIGraphicsBeginImageContextWithOptions(emojiSize, NO, 0.0);
[emojiImage drawInRect:CGRectMake(0, 0, emojiSize.width, emojiSize.height)];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSTextAttachment *textAttachment = [NSTextAttachment new];
textAttachment.image = resizedImage;
// Replace placeholder with image
NSAttributedString *rep = [NSAttributedString attributedStringWithAttachment:textAttachment];
[string replaceCharactersInRange:matchRange withAttributedString:rep];
}
return [[NSMutableAttributedString alloc]initWithAttributedString:string];
}
注意: 用于正则表达式替换的图片需提前导入工程, plist文件如图所示, 前面的”[zuan]”是图片名为”zuan”的照片所对应的正则表达式 (实际对应方式以自己工程为准)
#
使用这两个方法对UILabel进行重写和封装制作一个简单的图文混排MixLabel
#import <UIKit/UIKit.h>
@interface MixedLabel : UILabel
- (instancetype)initWithFrame:(CGRect)frame withStr:(NSString *)str withColor:(UIColor *)color; /** 初始化的时候直接带着参数设置Label */
- (void)setContentWith:(NSString *)str withColor:(UIColor *)color;
/** 如果要改变字的颜色 也可以使用这个 */
@end
#import "MixedLabel.h"
#import "NSAttributedString+JTATEmoji.h"/** 这里引入上面的类目 */
@interface MixedLabel ()
@property (nonatomic, copy) NSString *tempStr;
@end
@implementation MixedLabel
- (instancetype)initWithFrame:(CGRect)frame withStr:(NSString *)str withColor:(UIColor *)color {
self = [super initWithFrame:frame];
if (self) {
self.tempStr = str;
if (str.length == 0) {
return self;
}
NSMutableAttributedString *tempStr = [[NSMutableAttributedString alloc] initWithString:str];
[tempStr addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0,str.length)];
self.attributedText = [NSMutableAttributedString eemojiAttributedString:tempStr withFont:self.font];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
}
- (void)setContentWith:(NSString *)str withColor:(UIColor *)color {
NSMutableAttributedString *tempStr = [[NSMutableAttributedString alloc] initWithString:str];
[tempStr addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0,str.length)];
self.attributedText = [NSMutableAttributedString eemojiAttributedString:tempStr withFont:self.font];
}
MixLabel使用
self.mixLabel = [[MixedLabel alloc] initWithFrame:CGRectMake(ScaleX * 15, ScaleY * 10, WIDTH * 9 / 20, ScaleY * 30) withStr:@"[zan] 赞赞赞" withColor:THEMECOLOR]; /* 直接给颜色和 NSString即可 */
[self.mixLabel setContentWith:@"[xin] 猜你喜欢" withColor:XINCOLOR];