新浪微博客户端(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;

}

最终效果:

时间: 2024-10-11 06:28:44

新浪微博客户端(56)-拼接微博内容中的昵称,超链接,表情图片的相关文章

新浪微博客户端(55)-高亮显示微博内容中的昵称,话题,超链接

DJStatus.h #import <Foundation/Foundation.h> @class DJUser; /** 微博 */ @interface DJStatus : NSObject /** 微博id */ @property (nonatomic,copy) NSString *idstr; /** 微博内容 */ @property (nonatomic,copy) NSString *text; /** 微博内容(带属性) */ @property (nonatomic

Android新浪微博客户端(七)——ListView中的图片异步加载、缓存

原文出自:方杰|http://fangjie.sinaapp.com/?p=193转载请注明出处 最终效果演示:http://fangjie.sinaapp.com/?page_id=54该项目代码已经放到github:https://github.com/JayFang1993/SinaWeibo 一.ListView的图片异步加载 我们都知道对每一个Weibo Item都有用户头像,而且每一条微博还可能带有图片.如果在加载列表的同时加载图片,这样有几个缺点,第一很费事,界面卡住,用户体验很不

新浪微博客户端(58)-处理点击微博内容中的关键字

DJStatus.m // 创建一个用于包含特殊文本的集合 NSMutableArray *specialTextArray = [NSMutableArray array]; // 取出数组中的文本块进行拼接 for (DJStatusPart *part in statusParts) { NSAttributedString *subString = nil; if (part.isSpecial) { // 判断是否是特殊文本(若是特殊文本,则进行特殊处理,超链接:变色,表情文本:更换成

新浪微博客户端(22)-创建微博Cell

DJStatusCell.h #import <UIKit/UIKit.h> @class DJStatusCellFrame; @interface DJStatusCell : UITableViewCell /** DJStatusCell 的默认构造方法 */ + (instancetype)cellWithTableView:(UITableView *)tableView; @property (nonatomic,strong) DJStatusCellFrame *status

JS批量替换内容中关键词为超链接,避开已存在的链接和alt、title中的关键词

懂点seo的人都知道要给内容中关键词加上链接,形成站内锚文本链接,这对seo有很大的帮助. 思路就是在数据库中录入若干个关键词和关键词对应的链接,当然链接可以根据关键词的id自动生成,或者直接用关键词作为链接参数,如?tag=1.?kw=关键词. 这个问题不是简单的一个批量replace那么简单,要考虑到已经存在的超链接,不能将里面的文字再次替换为超链接,还有就是图片的alt属性,或者其他标签的title属性,里面的文字也不该被替换. 见下面的HTML代码: [<a href="http:

新浪微博客户端(30)-制作微博中的九宫格相册图片

DJStatusPhotosView.h #import <UIKit/UIKit.h> @interface DJStatusPhotosView : UIView @property (nonatomic,strong) NSArray *photos; /** 根据相册图片个数计算相册尺寸 */ + (CGSize)sizeWithCount:(NSUInteger)count; @end DJStatusPhotosView.m #import "DJStatusPhotos

零授权 抓取新浪微博任何用户的微博内容

一.微博API 使用微博API获取数据是最简单方便,同时数据完整性高的方式,缺点是微博开发平台对于API的调用次数做了严格的限制.具体使用过程参考http://open.weibo.com/,有详细的教程,对于API次数的限制,我们是通过注册多个开发者账号来绕过,对于某个IP调用API次数的限制,暂时没办法解决.微博API是通过httpclient发起请求,返回json形式的数据.对于数据重复获取方面,也有专门的接口通过参数控制获取增量数据.优点:简单,数据完整性高,增量简单.缺点:API次数有

新浪微博客户端(29)-格式化微博来源显示

DJStatus.m // 更新来源显示 - (void)setSource:(NSString *)source { NSRange range; range.location = [source rangeOfString:@">"].location + 1; range.length = [source rangeOfString:@"<" options:NSBackwardsSearch].location - range.location;

防微博内容展示,使用Html.fromHtml(),解决内容不能换行的问题

使用Html.fromHtml(),解决内容不能换行的问题,模仿微博内容展示效果. 一.需求要实现的效果 如下图中箭头指向的微博内容部分,包含超链接,点击超链接后要跳转到相应的WebView页面.(csdn上传图片试了好多遍也不成功,大家脑补一下吧,辛苦了).    二. 实现思路 首先获取网络数据,通过Html.fromHtml()解析获取到的数据,这时超链接<a></a>.段落符<p>.换行符<br>等将会被展示成对应的表现形式,就会出现上图所示的效果.