基于NSAttributedString与正则表达式实现的图文混排

来源:互联网 发布:mac版pdf如何修改文字 编辑:程序博客网 时间:2024/05/04 04:27

说明:
本文通过类目为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];

Demo : https://github.com/GyqGbusername/MixLabel.git

0 0