zoukankan      html  css  js  c++  java
  • 新浪微博客户端(56)-拼接微博内容中的昵称,超链接,表情图片

    DJStatusPart.h

    #import <Foundation/Foundation.h>
    
    @interface DJStatusPart : NSObject
    
    /** 文本块内容 */
    @property (nonatomic,copy) NSString *text;
    /** 文本块范围 */
    @property (nonatomic,assign) NSRange range;
    /** 当前文本块是否是特殊文本(昵称,超链接,Emoji) */
    @property (nonatomic,assign,getter=isSpecial) BOOL isSpecial;
    /** 当前文本块是否是表情图片 */
    @property (nonatomic,assign,getter=isEmotion) BOOL isEmotion;
    
    @end

    DJStatus.m

    // 设置带属性的文本内容
    - (void)setText:(NSString *)text {
    
        _text = text;
        
        // 将微博内容文本转换为带属性的微博内容文本
        NSMutableAttributedString *attributedText = [self attributedTextWithText:text];
        [attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, attributedText.length)];
        
        // 行间距
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        [paragraphStyle setLineSpacing:2];
        [attributedText addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedText.length)];
        
        _attributedText = attributedText;
    }
    
    
    
    - (void)setRetweeted_status:(DJStatus *)retweeted_status {
    
        _retweeted_status = retweeted_status;
        
        DJUser *retwetedUser = retweeted_status.user;
        NSString *retweetedText = [NSString stringWithFormat:@"@%@: %@",retwetedUser.name,retweeted_status.text];
        
        // 将转发内容文本转换为带属性的微博内容文本
        NSMutableAttributedString *attributedText = [self attributedTextWithText:retweetedText];
        [attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:13] range:NSMakeRange(0, attributedText.length)];
        
        // 行间距
        NSMutableParagraphStyle *paragraphSytle = [[NSMutableParagraphStyle alloc] init];
        [paragraphSytle setLineSpacing:2];
        [attributedText addAttribute:NSParagraphStyleAttributeName value:paragraphSytle range:NSMakeRange(0, attributedText.length)];
        
        _retweetedAttributedText = attributedText;
        
    }
    
    
    
    /** 普通文本->属性文本 */
    - (NSMutableAttributedString *)attributedTextWithText:(NSString *)text {
        
        // 表情的规则
        NSString *emotionPattern = @"\[[0-9a-zA-Z\u4e00-\u9fa5]+\]";
        // @的规则
        NSString *atPattern = @"@[0-9a-zA-Z\u4e00-\u9fa5-_]+";
        // #话题#的规则
        NSString *topicPattern = @"#[0-9a-zA-Z\u4e00-\u9fa5]+#";
        // url链接的规则
        NSString *urlPattern = @"\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))";
        NSString *pattern = [NSString stringWithFormat:@"%@|%@|%@|%@", emotionPattern, atPattern, topicPattern, urlPattern];
        
        // 利用当前文本生成attributedText
        NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
        
        NSMutableArray *statusParts = [NSMutableArray array];
        
        // 遍历并截取所有特殊文本
        [text enumerateStringsMatchedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
            
            // 过滤掉长度为0的空字符串
            if ((*capturedStrings).length == 0) return;
            
            DJStatusPart *statusPart = [[DJStatusPart alloc] init];
            statusPart.text = *capturedStrings;
            statusPart.range = *capturedRanges;
            statusPart.isSpecial = YES;
            statusPart.isEmotion = [(*capturedStrings) hasPrefix:@"["] && [(*capturedStrings) hasSuffix:@"]"]; // 若当前文本块以[]打头和结尾,则认为是表情
            [statusParts addObject:statusPart];
            
        }];
        
        
        // 遍历并截取所有非特殊文本
        [text enumerateStringsSeparatedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
            
            // 过滤掉长度为0的空字符串
            if ((*capturedStrings).length == 0) return;
            
            DJStatusPart *statusPart = [[DJStatusPart alloc] init];
            statusPart.text = *capturedStrings;
            statusPart.range = *capturedRanges;
            statusPart.isSpecial = NO;
            statusPart.isEmotion = NO;
            [statusParts addObject:statusPart];
            
        }];
        
        
        // 对添加完毕的statusParts数组进行排序
        [statusParts sortUsingComparator:^NSComparisonResult(DJStatusPart *  _Nonnull obj1, DJStatusPart *  _Nonnull obj2) {
            
            if (obj1.range.length > obj2.range.location) {
                return NSOrderedDescending; // 如果第一个文本块的位置坐标大于第二个,则为降序,否则为升序
            }
            return NSOrderedAscending;
        }];
        
        // 取出数组中的文本块进行拼接
        for (DJStatusPart *part in statusParts) {
         
            NSAttributedString *subString = nil;
            if (part.isSpecial) { // 判断是否是特殊文本(若是特殊文本,则进行特殊处理,超链接:变色,表情文本:更换成表情图片)
                if (part.isEmotion) { // 判断当前文本块是否是表情
                    
                    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
                    attachment.image = [UIImage imageNamed:@"EmotionIcons/default/d_aini"];
                    attachment.bounds = CGRectMake(0, -4, 16, 16);
                    subString = [NSAttributedString attributedStringWithAttachment:attachment];
                    
                } else { // 超链接&昵称
                    subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : [UIColor blueColor]}];
                }
            } else { // 不做任何处理
                subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : [UIColor redColor]}];
            }
    
            [attributedText appendAttributedString:subString];
        }
        return attributedText;
        
    }

    最终效果:

  • 相关阅读:
    MySQL 字符串与时间操作函数
    Redis消息订阅,事务,modules
    Redis数据结构
    Redis数据类型String
    Redis
    网络协议原理和lvs三种模型,调度算法和keepalived
    TCP连接状态,SYNC_RECV,CLOSE_WAIT,TIME_WAIT
    arp_ignore和arp_announce
    JMH和Disrupter
    容器CopyOnWriteList,ConcurrentHashMap,ConcurrentSkipListMap,BlockingQueue
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/6166281.html
Copyright © 2011-2022 走看看