zoukankan      html  css  js  c++  java
  • iOS之图文混排

    首先从github下载 https://github.com/wezm/RegexKitLite
    导入.h和.m文件后为RegexKitLite.m添加编译标记-fno-objc-arc。添加动态库libicucore.dylib

      UITextView *tv = [[UITextView alloc]init];
        tv.x = 20;
        tv.y = 200;
        [self.view addSubview:tv];


    1初始化一个属性字符串

    NSString *text = @"https://www.baidu.com 今天发送了[笑cry]一件很有意思的事情[笑尿]。";
    //2 指定匹配规则
       // 表情的规则
        NSString *emotionPattern = @"\[[a-zA-Z\u4e00-\u9fa5]+\]";
        // @的规则
        NSString *atPattern = @"@[0-9a-zA-Z\u4e00-\u9fa5-_]+";
        // #话题#的规则
        NSString *topicPattern = @"#[0-9a-zA-Z\u4e00-\u9fa5]+#";
        // url链接的规则
        NSString *urlPattern = @"[a-zA-z]+://[^\s]*";
        //3 对匹配到的范围进行高亮,只需要调用NSMutableAttributedString的addAttribute:::属性对特定范围的文字设置颜色属性。
        NSString *pattern = [NSString stringWithFormat:@"%@|%@|%@|%@",atPattern,emotionPattern,topicPattern,urlPattern];

        // 把[表情]替换成attachment图片,不能用replace和insert,因为会改变后面的相对位置,应该先拿到所有位置,最后再统一修改。
        // 应该打散特殊部分和非特殊部分,然后拼接。
        NSMutableArray *parts = [NSMutableArray array];
        
     
        
        [text enumerateStringsMatchedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
            
            if ((*capturedRanges).length == 0) return;
            
            TextSegment *seg = [[TextSegment alloc] init];
            seg.text = *capturedStrings;
            seg.range = *capturedRanges;
            seg.special = YES;
            //判断是否是表情,表情的特点是有[ ]
            seg.emotion = [seg.text hasPrefix:@"["] && [seg.text hasSuffix:@"]"];
            
            [parts addObject:seg];
        }];
        
        [text enumerateStringsSeparatedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
            
            if ((*capturedRanges).length == 0) return;
            
            TextSegment *seg = [[TextSegment alloc] init];
            seg.text = *capturedStrings;
            seg.range = *capturedRanges;
            seg.special = NO;
            [parts addObject:seg];
            
        }];
        
        //通过上面的代码,我们把所有的文字部分都放入了parts数组中,为了拼接方便,我们应该按照位置的起始排序,从前到后依次拼接。
        //这就需要对parts数组依据模型的range.location属性排序,比较常用的是根据block排序。
        //block传入两个数组中的对象obj1、obj2,要求返回排序规则NSOrderedAscending、NSOrderedSame、NSOrderedDescending。
        //NSOrderedAscending指的是obj1<obj2,系统默认按照升序排序,因此为了实现升序,发现obj1<obj2应该返回NSOrderedAscending。
        [parts sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            
            TextSegment *ts1 = obj1;
            TextSegment *ts2 = obj2;
            
            // Descending指的是obj1>obj2
            // Ascending指的是obj1<obj2
            // 要实现升序,按照上面的规则返回。
            
            // 系统默认按照升序排列。
            if (ts1.range.location < ts2.range.location) {
                return NSOrderedAscending;
            }
            
            return NSOrderedDescending;
            
        }];
        
        //接下来只需要从前到后拼接一个新创建的NSAttributedString,根据内容的不同拼接不同的内容。
        NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
        
        //保存特殊文字
        [self.specialSegments removeAllObjects];
        
        NSInteger cnt = parts.count;
        for (NSInteger i = 0; i < cnt; i++) {
            TextSegment *ts = parts[i];
            if (ts.isEmotion) {
                NSTextAttachment *attach = [[NSTextAttachment alloc] init];
                attach.image = [UIImage imageNamed:@"003"];
                attach.bounds = CGRectMake(0, -3, 15, 15);
                NSAttributedString *emotionStr = [NSAttributedString attributedStringWithAttachment:attach];
                [attributedText appendAttributedString:emotionStr];
            }else if(ts.isSpecial){
                NSAttributedString *special = [[NSAttributedString alloc] initWithString:ts.text attributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
                // 保存所有特殊文字的内容和位置,保存到模型,再把模型存入数组。
                TextSpecial *spec = [[TextSpecial alloc] init];
                spec.text = ts.text;
                NSInteger loc = attributedText.length;
                NSInteger len = ts.text.length;
                spec.range = NSMakeRange(loc, len);
                [self.specialSegments addObject:spec];
                
                [attributedText appendAttributedString:special];
            }else{
                
                [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:ts.text attributes:@{NSForegroundColorAttributeName:[UIColor greenColor]}]];
            }
            
        }
        //必须这是这个值,不然高度不够
        [attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, attributedText.length)];
        
        //然后调用boundingRectWithSize:计算尺寸,注意options必须选择options:NSStringDrawingUsesLineFragmentOrigin才能得到正确尺寸。
        CGSize contentSize = [attributedText boundingRectWithSize:CGSizeMake(320, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

     
        tv.size = contentSize;
        tv.specialSegments = [self.specialSegments copy];
        tv.attributedText = attributedText;

  • 相关阅读:
    改变文件属性和权限
    Linux文件属性
    Linux 学习笔记
    一些常见的第三方UI库
    list转化为json数组
    在js文件里调用另一个js文件里的函数
    Intellij idea创建maven项目并配置tomcat
    使用JS语句,利用for循环的方法创建表格的两种方法
    intellij idea 破解教程
    Jquery中的DOM操作:
  • 原文地址:https://www.cnblogs.com/xsiOS/p/5125120.html
Copyright © 2011-2022 走看看