NSTextAttachment objects are used by the NSAttributedString class cluster as the values for attachment attributes (stored in the attributed string under the key named NSAttachmentAttributeName).

UILabel

下面通过例子,给UILabel的文字后面跟上一个emoji:

    //创建NSTextAttachmentNSTextAttachment *attachment = [[NSTextAttachment alloc] init];attachment.image = [UIImage imageNamed:@"emoji"];NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"后面跟着图片"];[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 6)];[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:NSMakeRange(0, 6)];NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];[attributedString insertAttributedString:attachmentString atIndex:6];//设置attributedText_label.attributedText = attributedString;

效果如下:

上图的例子中,emoji图片偏大,位置也偏上,如何调整?参考Center NSTextAttachment image next to single line UILabel。

可以通过调整bounds来解决:

    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];attachment.image = [UIImage imageNamed:@"emoji"];attachment.bounds = CGRectMake(0, -5, 20, 20);

调整之后的效果如下:

也可以继承NSTextAttachment,然后重写- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex方法:

@interface MYNSAttachment : NSTextAttachment@end@implementation MYNSAttachment- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
{return CGRectMake( 0 , -5 , lineFrag.size.height , lineFrag.size.height);
}@end

请参考:

  • 用 NSAttributedString 在文字行中加入圖片
  • NSTextAttachment 的使用
  • Core Text 入门

UITextView

转载自UITextView编辑时插入自定义表情-简单的图文混编

前言

在iOS开发中,经常需要用UITextView作为编辑文本的输入控件。
但是如何在编辑时插入自定义表情呢?就是像发微博时那样?

本文简单的用NSTextAttachment、NSAttributedString的特性,实现了

  • 在UITextView中编辑文字时插入自定义表情图片
  • 同时可以返回带有表情“替换符”的纯文本字符串。

示例

本文代码工程地址:https://github.com/zekunyan/UITextViewDIYEmojiExample

效果图:

背景知识

  • NSAttributedString及其子类,用于显示富文本。
  • NSTextAttachment,NSAttributedString的一种样式类,可以在文本中显示图片。
  • NSTextStorage,UITextView中的实际的文本封装。(见参考中的UITextView文档)

表情与其标志

首先需要明确的是,我们的自定义表情一定是有一一对应的“标志”的,如“[/emoji_haha]”。
就是说,为了方便处理,方便在数据库、网络传输中保存、传输带有表情图片的文本,我们必须要为每种表情取特定的“名字”,数据库中储存的、网络传输的文本就只包含这些标志名字就行,在显示的时候做对应的替换。

如:
tutuge.me

对应的纯文本就是:
tutuge.me[/emoji_1]

插入并显示表情图片

插入表情很简单,直接实例化NSTextAttachment类,将需要的表情的UIImage实例赋值给NSTextAttachment的image属性,然后用“[NSAttributedString attributedStringWithAttachment:]”方法实例化一个NSAttributedString的对象,插入到UITextView的textStorage对应的位置即可。

如下:

NSTextAttachment *emojiTextAttachment = [NSTextAttachment new];//设置表情图片
emojiTextAttachment.image = emojiImage;//插入表情
[textView.textStorage insertAttributedString:[NSAttributedString attributedStringWithAttachment:emojiTextAttachment]atIndex:textView.selectedRange.location];

这样,就能在UITextView当前光标位置插入表情图片了。

获取带有表情标志的文本字符串

难点

NSTextAttachment被插入到NSAttributedString中的时候,就被当成了一个字符处理!!!。
就是说,只从UITextView的text中,是找不回文本里面不同的表情所对应的标志的!

解决点

  1. 我们要能遍历出当前文本中所有的表情,也就是NSTextAttachment类。
  2. 我们要能知道遍历出的表情,对应的标志是什么。

遍历所有的NSTextAttachment类属性

遍历,嗯,先看看Apple有没有提供相应的方法,能遍历NSAttributedString(及其子类)的属性的。查阅文档:NSAttributedString Class Reference,可以找到这么一个方法:“- enumerateAttribute:inRange:options:usingBlock:”,其原型如下:

- (void)enumerateAttribute:(NSString *)attrNameinRange:(NSRange)enumerationRangeoptions:(NSAttributedStringEnumerationOptions)optsusingBlock:(void (^)(id value,NSRange range,BOOL *stop))block

用处:

Executes the Block for the specified attribute run in the specified range.

看,就是这个方法~就能遍历出NSTextAttachment对象了~

创建NSTextAttachment的子类

如何绑定NSTextAttachment所表示的表情和与其对应的标志?创建子类嘛~直接在子类中增加属性,保存标志不就行了。
如下:

@interface EmojiTextAttachment : NSTextAttachment
@property(strong, nonatomic) NSString *emojiTag;
@end

所以,这个时候,插入表情的代码应该就是下面这样:

EmojiTextAttachment *emojiTextAttachment = [EmojiTextAttachment new];//保存表情标志
emojiTextAttachment.emojiTag = emojiTag;//设置表情图片
emojiTextAttachment.image = emojiImage;//插入表情
[textView.textStorage insertAttributedString:[NSAttributedString attributedStringWithAttachment:emojiTextAttachment]atIndex:textView.selectedRange.location];

创建NSAttributedString的Category

最后,就是将这个遍历表情、拼接最终文本字符串的方法设置成NSAttributedString的自定义Category方法,以方便直接调用。
当然,这里面有些细节的处理,如替换表情标志时的字符串偏移量计算等,看代码吧。

如下:

//NSAttributedString+EmojiExtension.h@interface NSAttributedString (EmojiExtension)
- (NSString *)getPlainString;
@end//NSAttributedString+EmojiExtension.m@implementation NSAttributedString (EmojiExtension)- (NSString *)getPlainString {//最终纯文本NSMutableString *plainString = [NSMutableString stringWithString:self.string];//替换下标的偏移量__block NSUInteger base = 0;//遍历[self enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.length)options:0usingBlock:^(id value, NSRange range, BOOL *stop) {//检查类型是否是自定义NSTextAttachment类if (value && [value isKindOfClass:[EmojiTextAttachment class]]) {//替换[plainString replaceCharactersInRange:NSMakeRange(range.location + base, range.length)withString:((EmojiTextAttachment *) value).emojiTag];//增加偏移量                          base += ((EmojiTextAttachment *) value).emojiTag.length - 1;}}];return plainString;
}@end

使用

直接调用getPlainString方法即可。

总结

其实本文也是来源于最近的项目需求,在网上一直找不到比较好的解决方案,就自己摸索出来一个。至于复杂的图文混合编辑,当然还是Core Text来的强大(自己也在学习中)~

如果有更好地办法,一定要告诉我啊~~~

参考

  • UITextView Class Reference
  • NSAttributedString Class Reference

转载自UITextView编辑时插入自定义表情-续-自定义表情图片的大小

前言

本文是基于UITextView编辑时插入自定义表情-简单的图文混编写的,主要实现了在UITextView插入表情图片时,自定义表情大小的功能。

Github

本文代码工程地址:https://github.com/zekunyan/UITextViewDIYEmojiExample

Gif示例图

关键点

首先要明确我们要什么,很简单,就是指定NSTextAttachment在被绘制时的大小。

所以,按照这个思路,就可以去找找NSTextAttachment类的相关方法,看能不能通过继承或其他的方式改变大小。

幸运的是,NSTextAttachment实现了“NSTextAttachmentContainer”这个Protocol,而这个Protocol里面有如下方法:

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainerproposedLineFragment:(CGRect)lineFragglyphPosition:(CGPoint)positioncharacterIndex:(NSUInteger)charIndex

再看看其解释:

Returns the layout bounds of the text attachment to the layout manager. (required)

也就是说,在绘制NSTextAttachment的内容的时候,内容的“Bounds”是通过这个方法获得的。所以,可以重写这个方法,来达到我们的目的。

继续扩展NSTextAttachment类

保存自定义Size

根据之前的定义,我们在自定义的类“EmojiTextAttachment”中再加一个保存大小的属性,如下:

//EmojiTextAttachment类定义@interface EmojiTextAttachment : NSTextAttachment
//表情的字符串表示,见前文
@property(strong, nonatomic) NSString *emojiTag;//新增:保存当前表情图片的大小
@property(assign, nonatomic) CGFloat emojiSize;
@end

有了“emojiSize”这个属性,我们就可以在自由的指定每个NSTextAttachment的大小。

重写

接下来就是重写方法,不多说,见代码:

//EmojiTextAttachment实现@implementation EmojiTextAttachment//重点!重写NSTextAttachmentContainer Protocol的方法
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {//根据emojiSize计算新的大小return [self scaleImageSizeToWidth:_emojiSize];
}//计算新的图片大小
//这里不涉及对图片实际数据的压缩,所以不用异步处理~- (CGRect)scaleImageSizeToWidth:(CGFloat)width {//缩放系数CGFloat factor = 1.0;//获取原本图片大小CGSize oriSize = [self.image size];//计算缩放系数factor = (CGFloat) (width / oriSize.width);//创建新的SizeCGRect newSize = CGRectMake(0, 0, oriSize.width * factor, oriSize.height * factor);return newSize;}
@end

使用

增加了emojiSize属性后,我们就可以在创建表情,甚至创建后,自由的调整每个NSTextAttachment的大小。

总结

一共只增加了十几行代码,但是效果还是不错哒~

UILabelUITextView文本嵌入图片处理相关推荐

  1. hp-socket 文本跟图片同时发送_文本、截图和应用,这样「包装」一秒变美观

    社交网络被发明出来的一个重要目的就是分享,无论是所见所闻还是喜怒哀乐,亦或是脑海中突然迸发出的一段妙言,某个转瞬即逝的精彩瞬间,一篇深度好文,一个在少数派看到的绝赞应用-- 分享内容丰富多彩,相比之下 ...

  2. 【tkGo】将Excel里的图片链接替换为图片(Excel嵌入图片)

    1 背景 因为某些原因,我们的Excel里会放入一些图片链接,但查看的时候需要一个个点开,通过浏览器显示,非常麻烦. 我们可以通过python的openpyxl这个库来解决此问题,一键替换所有链接为图 ...

  3. java word文本框_Java 读取Word文本框中的文本、图片、表格

    Word可插入文本框,文本框中可嵌入文本.图片.表格等内容.对文档中的已有文本框,也可以读取其中的内容.本文以Java程序代码来展示如何读取文本框,包括读取文本框中的文本.图片以及表格等. [程序环境 ...

  4. python使用fpdf创建pdf:写入hello world、嵌入图片

    python使用fpdf创建pdf:写入hello world.嵌入图片 pip install fpdf # 创建pdf并写入hello world文本内容: # 嵌入图片 from fpdf im ...

  5. 12.6学习笔记 HTML5表单元素/嵌入图片/视频(未完)

    12.6学习笔记 一. HTML 表单元素(下) 二. HTML5嵌入图片与创建分区响应图 三. HTML5嵌入视频 一. HTML 表单元素(下) 主要内容: 用input元素获取有规定格式的字符串 ...

  6. Java 读取Word文本框中的文本、图片、表格

    Word可插入文本框,文本框中可嵌入文本.图片.表格等内容.对文档中的已有文本框,也可以读取其中的内容.本文以Java程序代码来展示如何读取文本框,包括读取文本框中的文本.图片以及表格等. [程序环境 ...

  7. itext pdf 嵌入图片问题

    1. table 内嵌入图片 PdfPTable table = new PdfPTable(5);PdfPCell pdfPCell = new PdfPCell(); //Image image ...

  8. 【Python】导出docx格式Word文档中的文本、图片和附件等

    [Python]导出docx格式Word文档中的文本.图片和附件等 零.需求 为批量批改学生在机房提交的实验报告,我需要对所有的实验文档内容进行处理.需要批量提取Word文档中的图片和附件以便进一步检 ...

  9. 网络知识入门,Web服务器的CGI程序,浏览器如何判断响应内容:文本,图片还是音频文件?(十九)

    目录 将请求的uri转换为实际的文件名 运行CGI程序 web服务器的访问控制 浏览器接受响应并返回内容 浏览器接受响应消息后如何显示内容 浏览器显示网页内容:访问完成 将请求的uri转换为实际的文件 ...

最新文章

  1. WebAPI增加Area以支持无限层级同名Controller
  2. 存储组件的实现思路分析及代码实现
  3. hadoop job 未跑满资源_mapreduce任务占满整个集群资源
  4. 2019年如何打造自己的“前端品牌”
  5. Silverlight实用窍门系列:51.Silverlight页面控件的放大缩小、Silverlight和Html控件的互相操作...
  6. tcl mysql_MySQL·TCL语言
  7. lol1月8日服务器维护,LOL1月16日更新维护到几点 8.1版本更新内容
  8. python mysqldb insert_python MySQLdb使用教程详解
  9. 解析vue-ssr构建流程
  10. pytorch之tensor操作expand
  11. 怎么做游戏打击感浅述
  12. 24小时学通LINUX内核系列
  13. java年龄不能超过120,systemd 代码行数超过 120 万,创始人贡献的 commits 最多
  14. 高等数学第七版同济大学课后习题讲解上下册
  15. 计算机休眠唤醒后 网络受限,彻底解决win10系统待机、休眠被唤醒后笔记本WIFI无线网无法连接的问题-网络教程与技术 -亦是美网络...
  16. 二级域名分发系统源码
  17. 彻底理解 Window 和 WindowManager
  18. Nat. Commun. | 基于最优传输的单细胞数据集成统一计算框架
  19. 3dsmax uvw展开
  20. LeetCode 885 救生艇

热门文章

  1. 【B站商品搜索】快速了解平台商品需求,全方位解读爆款商品数据!
  2. ubuntu 20.04 启用kdump服务及下载vmlinux
  3. 刚构桥的优缺点_刚构桥特点
  4. 英文版权声明_干货 | 英文自我介绍,刚说了quot;my name is ...quot;就被pass了
  5. 用selenium模拟浏览器爬取淘宝订单信息
  6. labview2020图文教程LabVIEW2020
  7. mysql 主master 从 slaver 复制 配置详细
  8. Java 学习 Day17 多线程
  9. H2数据库使用与管理入门
  10. 用手机的同志们都来看看吧 有多少真相我们一直不知道 ……