iOS NSAttributedString 图文混排 UILabel 可折叠 展开

RZColorful

NSAttributedString 富文本方法 (图文混排、多样式文本)
UILabel 可折叠 展开 可点击文本

Installation

pod 'RZColorful'

Author

rztime, rztime@vip.qq.com

swift版本RZColorfulSwift

UITextView实现的富文本编辑器RZRichTextView

  • NSAttributedString 的多样化设置(文字字体、颜色、阴影、段落样式、url、下划线,以及图文混排等等)
  • 添加UITextField、UITextView、UILabel的attributedText的富文本设置。
  • 扩展:添加一个刷新界面时保持文本框焦点的方法 demo查看
  • 富文本方法内容可单独抽出来,在下边这个文件夹中
#import "NSAttributedString+RZColorful.h"

关于RZColorful

  • 支持UILabel、UITextView、UITextField的attributedText的设置。
  • 支持获取NSAttributedString中的图片
  • 支持 HTML 与 NSAttributedString互换(支持图片)
  • 包含的属性快捷设置:
    • 段落样式
    • 阴影
    • 文本字体、颜色
    • 文本所在区域对应的背景颜色
    • 连体字
    • 字间距
    • 删除线、下划线,及其线条颜色
    • 描边,及其颜色
    • 斜体字
    • 拉伸
    • 上下标
    • 书写方向(从左到右,从右到左)
    • 通过html源码加载富文本
    • 通过url添加图片到富文本

How to use

  • 请在需要使用的地方加上
#import "RZColorful.h"
  • 主要的功能:
    • RZColorfulConferrer

      • text -- 添加文本
      • htmlText -- 添加html源码
      • image -- 添加图片
      • imageByUrl -- 添加图片(通过图片的URL添加)
      • paragraphStyle -- 全局的段落样式
      • shadow -- 全局的阴影样式
    • RZColorfulAttribute -- 设置文本的所有的属性

    • RZImageAttachment -- 设置图片的所有的属性

讲解

  • RZColorfulConferrerparagraphStyleshadow 属于全局的设置,在block中任何位置都可设置
  • 文字和图片都可设置paragraphStyleshadow,对齐方式是paragraphStylealignment,设置后,当前行文字图片的全局样式将被此覆盖,即全局样式无效,不影响其他行。

基本的简单使用方法

    [cell.textLabel rz_colorfulConfer:^(RZColorfulConferrer * _Nonnull confer) {
        confer.paragraphStyle.paragraphSpacing(15); // 设置段落之间的行距

        confer.text(@"日常用处:(图片+标题+描述)\n").font(rzFont(17)).textColor([UIColor redColor]);

        confer.appendImage([UIImage imageNamed:@"test.jpg"]).bounds(CGRectMake(0, -2, 15, 15)); // 图片
        confer.text(@" 姓        名: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11));
        confer.text(@"rztime").font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));

        confer.text(@"\n");
        confer.appendImage([UIImage imageNamed:@"test.jpg"]).bounds(CGRectMake(0, -2, 15, 15));
        confer.text(@" 时        间: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11));
        confer.text([NSString stringWithFormat:@"%@", [NSDate new]]).font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));

        confer.text(@"\n");
        confer.appendImage([UIImage imageNamed:@"test.jpg"]).bounds(CGRectMake(0, -2, 15, 15));
        confer.text(@" 当次消费: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11));
        confer.text(@"¥").font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));
        confer.text(@"100").font(rzFont(15)).textColor(RGBA(251, 51, 51, 1));
        confer.text(@"元").font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));
    }];

段落样式、阴影(局部与全局统一的区别)

如果设置有局部样式,则全局样式无效

    [cell.textLabel rz_colorfulConfer:^(RZColorfulConferrer * _Nonnull confer) {
        confer.paragraphStyle.lineSpacing(5).paragraphSpacingBefore(5).alignment(NSTextAlignmentCenter); // 段落全局样式
        confer.shadow.color(RGBA(255, 0, 0, 0.3)).offset(CGSizeMake(1, 1));   // 阴影全局
        
        // 此部分显示全局样式的风格 (红色阴影,居中对齐,段落行距等)
        confer.appendImage([UIImage imageNamed:@"test.jpg"]).bounds(CGRectMake(0, -2, 15, 15));
        confer.text(@" 姓名: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11));
        confer.text(@"rztime").font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));
        
        confer.text(@"\n");
        confer.appendImage([UIImage imageNamed:@"test.jpg"]).bounds(CGRectMake(0, -2, 15, 15));
        confer.text(@" 时间: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11));
        confer.text([NSString stringWithFormat:@"%@", [NSDate new]]).font(rzFont(15)).textColor(RGBA(51, 51, 51, 1));
        
        // 此部分显示全局样式的风格 (居中对齐,段落行距等)  阴影将被局部覆盖(灰色)
        confer.text(@"\n地址: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11)).paragraphStyle.paragraphSpacingBefore(20).and.shadow.color(GRAY(151)).offset(CGSizeMake(3, 3));;
        confer.text(@"成都-软件园").font(rzFont(15)).textColor(RGBA(51, 51, 51, 1)).shadow.color(GRAY(151)).offset(CGSizeMake(3, 3));
        
        // 此部分段落样式被局部覆盖  阴影显示全局的
        confer.text(@"\n爱好: ").font(rzFont(15)).textColor(RGBA(151, 151, 151, 11)).paragraphStyle.paragraphSpacingBefore(20);
        confer.text(@"游山、").font(rzFont(15)).textColor(RGBA(151, 51, 51, 1));
        confer.text(@"玩水、").font(rzFont(10)).textColor(RGBA(51, 151, 51, 1));
        confer.text(@"听歌、").font(rzFont(18)).textColor(RGBA(51, 51, 151, 1));
        confer.text(@"美食、").font(rzFont(17)).textColor(RGBA(51, 151, 51, 1));
        confer.text(@"看电影、").font(rzFont(16)).textColor(RGBA(151, 51, 51, 1));
        confer.text(@"撸代码、").font(rzFont(15)).textColor(RGBA(51, 151, 51, 1));
        confer.text(@"等等\n\n").font(rzFont(15)).textColor(RGBA(251, 51, 51, 1));
    }];

通过url加载图片

    [cell.textLabel rz_colorfulConfer:^(RZColorfulConferrer * _Nonnull confer) {
        confer.appendImageByUrl(@"http://pic28.photophoto.cn/20130830/0005018667531249_b.jpg").bounds(CGRectMake(0, 0, 200, 0)).paragraphStyle.alignment(NSTextAlignmentLeft); // 宽或高为0时,即自动宽/高按照图片比例来
    }];

通过html源码加载文本

    NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
    NSString *filePath =[resourcePath stringByAppendingPathComponent:@"test.html"];
    NSString *htmlstring=[[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[cell.textLabel rz_colorfulConfer:^(RZColorfulConferrer * _Nonnull confer) {
    confer.htmlText(htmlstring);
}];

给UILabel添加富文本可点击功能 给文本添加tapActionByLable属性

[_label rz_colorfulConfer:^(RZColorfulConferrer * _Nonnull confer) {
    confer.text(@"可点击的:").font([UIFont systemFontOfSize:17]).textColor(UIColor.blackColor);
    confer.text(@"文本").font([UIFont systemFontOfSize:17]).textColor(UIColor.redColor).tapActionByLable(@"1");
}];
[_label rz_tapAction:^(UILabel * _Nonnull label, NSString * _Nonnull tapActionId, NSRange range) {
    NSLog(@"%@", tapActionId); // print: 1
}];

给UILabel添加超行之后的折叠、展开功能

UILabel

/// 设置富文本(超过行数后,自动追加“展开” “收起”)
/// @param attr 原文
/// @param line 最大显示行数
/// @param width 最大显示宽度,这个宽度用于计算文本行
/// @param fold 当前是否折叠
/// @param allText 超过了行数之后,折叠状态显示的文本 如”展开“  需要给文本设置NSTapActionByLabel属性  (tapActionByLable)
/// @param foldText 超过行数之后,全部展开状态显示的文本  如”收起“  需要给文本设置NSTapActionByLabel属性 (tapActionByLable)
- (void)rz_setAttributedString:(NSAttributedString * _Nullable)attr maxLine:(NSInteger)line maxWidth:(CGFloat)width isFold:(BOOL)fold showAllText:(NSAttributedString *_Nullable)allText showFoldText:(NSAttributedString *_Nullable)foldText;

备注:

  • 多种属性使用名请参考对应的文件。
  • UILabel、UITextFile是同样的使用方法。
  • 在UILabel、UITextFiled上url点击方法无效。
  • 在UITextView中若要设置文本和图片的点击事件(即对文本和图片设置附带URL的属性),请先设置其editable = NO, 并实现代理。
    • 设置了URL属性的文本,内部自带蓝色和下划线,若要去掉,可设置 textView.linkTextAttributes = @{};
// 实现下列方法 (二选一、或都可以实现,当都返回YES时,可能会打开safari浏览器)
textView.rzDidTapTextView = ^BOOL(id  _Nullable tapObj) {
    NSString *url = tapObj;
    if ([tapObj isKindOfClass:[NSURL class]]) {
        url = [(NSURL *)tapObj absoluteString];
    }
    url = url.rz_decodedString;
            
    NSLog(@"rzDidTapTextView:tapObj:%@  \n如果url中包含了有中文,URL将会进行编码,所以请rz_decodedString解码之后查看:%@", tapObj, url);
    return NO;
};

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
    NSLog(@"URL:%@", URL);
    // return NO;则不跳转,这里可以做一些基本判断在执行是否跳转浏览器打开url
    return YES; 
}

注意

  • 尽管我已经在代码中已经处理过(弱)引用问题,但是在实际运用写入text时,还是请尽量检查避免循环引用

最后

  • 在使用过程中,如果您发现有什么问题,欢迎向我反馈,谢谢
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容