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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值