美文网首页IS移动开发总结
iOS2017 (NSString和NSAttributedSt

iOS2017 (NSString和NSAttributedSt

作者: brave_wu | 来源:发表于2017-04-04 23:46 被阅读2087次

    鉴于很多人浏览过本文,为了不让之前糟糕的格式浪费大家宝贵的时间我重新写了一篇更新版,亲们还是移步那篇把.

          最近研究了含表情的字符串,我们实现像😓的其实不难😓,输入法都支持😓,但是如果想换成自己需要的图片表情,甚至GIF动画表情,就要花一番功夫了😓😓😓😓。

    除了利用webview写HTML的方法外,有一种更加清明的方法,那就是属性字符串,即NSAttributedString、NSMutableAttributedString,顾名思义后者就是可变的而已。

    首先,先实现普通字符串转属性字符串吧(网上现成的😓):

    +(NSMutableAttributedString *)stringToAttributeString:(NSString *)text

    {

    //先把普通的字符串text转化生成Attributed类型的字符串

    NSMutableAttributedString * attStr = [[NSMutableAttributedString alloc]initWithString:text];

    NSString * zhengze = @"\\[\\([a-zA-Z0-9\u4e00-\u9fa5]+\\)\\]"; //正则表达式 ,例如  [(呵呵)] = 😑

    NSError * error;

    NSRegularExpression * re = [NSRegularExpression regularExpressionWithPattern:zhengze options:NSRegularExpressionCaseInsensitive error:&error];

    if (!re)

    {

    NSLog(@"%@😓",[error localizedDescription]);//打印错误😓

    }

    NSArray * arr = [re matchesInString:text options:0 range:NSMakeRange(0, text.length)];//遍历字符串,获得所有的匹配字符串

    NSBundle *bundle = [NSBundle mainBundle];

    NSString * path = [bundle pathForResource:@"emj" ofType:@"plist"];  //plist文件,制作一个 数组,包含文字,表情图片名称

    NSArray * face = [[NSArray alloc]initWithContentsOfFile:path];//获取 所有的数组

    //如果有多个表情图,必须从后往前替换,因为替换后Range就不准确了

    for (int j =(int) arr.count - 1; j >= 0; j--) {

    //NSTextCheckingResult里面包含range

    NSTextCheckingResult * result = arr[j];

    for (int i = 0; i < face.count; i++) {

    if ([[text substringWithRange:result.range] isEqualToString:face[i][@"key"]])//从数组中的字典中取元素

    {

    NSString * imageName = [NSString stringWithString:face[i][@"picture"]];

    NSTextAttachment * textAttachment = [[NSTextAttachment alloc]init];//添加附件,图片

    //textAttachment.bounds=CGRectMake(0, 0, 20, 20);//调节表情大小

    textAttachment.image = [UIImage imageNamed:imageName];

    NSAttributedString * imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment];

    [attStr replaceCharactersInRange:result.range withAttributedString:imageStr];//替换未图片附件

    break;

    }

    }

    }

    return attStr;

    }

    //==============😓=======================

    当然,你肯定会需要转回来😓:

    //把带有图片的属性字符串转成普通的字符串

    + (NSString *)textString:(NSAttributedString *)attributedText

    {

    NSMutableAttributedString * resutlAtt = [[NSMutableAttributedString alloc]initWithAttributedString:attributedText];

    EmoticonsHelper * helper = [EmoticonsHelper new];

    //枚举出所有的附件字符串

    [attributedText enumerateAttributesInRange:NSMakeRange(0, attributedText.length) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {

    NSTextAttachment * textAtt = attrs[@"NSAttachment"];//从字典中取得那一个图片

    if (textAtt)

    {

    UIImage * image = textAtt.image;

    NSString * text = [helper stringFromImage:image];

    [resutlAtt replaceCharactersInRange:range withString:text];

    }

    }];

    return resutlAtt.string;

    }

    //获取图片数组

    -(NSArray *)getAllImagePaths//数组结构还是上述的截图的数组结构

    {

    NSBundle *bundle = [NSBundle mainBundle];

    NSString * path = [bundle pathForResource:@"emojo" ofType:@"plist"];

    NSArray * face = [[NSArray alloc]initWithContentsOfFile:path];

    return face;

    }

    //=================================

    会不会需要属性字符串的尺寸大小呢?不用着急,直接有代码:

    +(CGSize)getAttributedTextSize:(NSString *)text

    {

    //先把普通的字符串text转化生成Attributed类型的字符串

    NSMutableAttributedString * attStr = [[NSMutableAttributedString alloc]initWithString:text];

    NSString * zhengze = @"\\[\\([a-zA-Z0-9\u4e00-\u9fa5]+\\)\\]";

    NSError * error;

    NSRegularExpression * re = [NSRegularExpression regularExpressionWithPattern:zhengze options:NSRegularExpressionCaseInsensitive error:&error];

    if (!re)

    {

    NSLog(@"正则表达式匹配错误%@" ,[error localizedDescription]);

    }

    NSArray * arr = [re matchesInString:text options:0 range:NSMakeRange(0, text.length)];

    if (!arr.count)//说明字符串中没有表情通配符,是普通的文本,则计算文本size

    {

    NSDictionary *dic=@{NSFontAttributeName: [UIFont systemFontOfSize:14]};

    CGSize size1=[text boundingRectWithSize:CGSizeMake(160, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil].size;

    if (size1.height<=60)

    {

    size1.height=60;

    }

    else

    {

    size1.height+=15;

    }

    return size1;

    }

    NSBundle *bundle = [NSBundle mainBundle];

    NSString * path = [bundle pathForResource:@"emj" ofType:@"plist"];

    NSArray * face = [[NSArray alloc]initWithContentsOfFile:path];

    //如果有多个表情图,必须从后往前替换,因为替换后Range就不准确了

    for (int j =(int) arr.count - 1; j >= 0; j--) {

    //NSTextCheckingResult里面包含range

    NSTextCheckingResult * result = arr[j];

    for (int i = 0; i < face.count; i++) {

    if ([[text substringWithRange:result.range] isEqualToString:face[i][@"key"]])

    {

    NSString * imageName = [NSString stringWithString:face[i][@"picture"]];

    NSTextAttachment * textAttachment = [[NSTextAttachment alloc]init];

    textAttachment.image = [UIImage imageNamed:imageName];

    NSAttributedString * imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment];

    [attStr replaceCharactersInRange:result.range withAttributedString:imageStr];

    break;

    }

    }

    }

    CGSize size2=[attStr boundingRectWithSize:CGSizeMake(180, 1000) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

    size2.height+=40;  //表情文字增加高度

    return size2;//返回属性字符串的尺寸

    }

    //==================================================

    当然,以上这些都是网上现成的😓,下面要写一点不一样的东西了🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄🙄

             首先我们知道和字符串相关的UI控件呢不外乎那么几种,怎么样利用上属性字符串呢😓?

    1、UITextView、UITextField

    以UITextView为例,假设你得到的属性字符串是NSAttributedString *result,我要显示出表情图片还得:

    [TextView.textStorage insertAttributedString:result TextView.selectedRange.location];

    TextView.selectedRange = NSMakeRange(TextView.selectedRange.location+1, 0);

    //重置格式

    NSRange wholeRange = NSMakeRange(0,TextView.textStorage.length);

    [TextView.textStorage removeAttribute:NSFontAttributeName range:wholeRange];

    [TextView.textStorage addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20.0f] range:wholeRange];

    这样不但能显示表情图片到你的TextView里😁,还能通过UIFont
    设置显示的大小。

    2、UILabel

    这个控件就不用多说了,直接有个属性名字叫attributedText,设上result
    就能显示了。

    本文就到此结束了🌹🌹🌹🌹🌹。。。。。

    相关文章

      网友评论

      • 爱的播放:推荐一款写富文本非常好用的控件:NudeIn,你完全不用去学习这些蛋疼的原生写法,可以像masonry那样写富文本控件
        github地址:https://github.com/hon-key/Nudeln
      • Corbin___:markdown’
      • 李小南:你好请问下, 你在根据NSRange替换[微笑]成表情的时候, 替换完成后, 后面的类似[大笑]的NSRange不会改变吗? 毕竟[微笑]和表情的长度不一样

      本文标题:iOS2017 (NSString和NSAttributedSt

      本文链接:https://www.haomeiwen.com/subject/yjazottx.html