UITextView编辑时插入自定义表情-简单的图文混编
2015-10-20 11:49
561 查看
原文:http://tutuge.me/2015/03/07/UITextView%E7%BC%96%E8%BE%91%E6%97%B6%E6%8F%92%E5%85%A5%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A1%A8%E6%83%85-%E7%AE%80%E5%8D%95%E7%9A%84%E5%9B%BE%E6%96%87%E6%B7%B7%E7%BC%96/
在iOS开发中,经常需要用UITextView作为编辑文本的输入控件。
但是如何在编辑时插入自定义表情呢?就是像发微博时那样?
本文简单的用NSTextAttachment、NSAttributedString的特性,实现了
在UITextView中编辑文字时插入自定义表情图片
同时可以返回带有表情“替换符”的纯文本字符串。
本文代码工程地址:https://github.com/zekunyan/UITextViewDIYEmojiExample
效果图:
image
NSAttributedString及其子类,用于显示富文本。
NSTextAttachment,NSAttributedString的一种样式类,可以在文本中显示图片。
NSTextStorage,UITextView中的实际的文本封装。(见参考中的UITextView文档)
首先需要明确的是,我们的自定义表情一定是有一一对应的“标志”的,如“[/emoji_haha]”。
就是说,为了方便处理,方便在数据库、网络传输中保存、传输带有表情图片的文本,我们必须要为每种表情取特定的“名字”,数据库中储存的、网络传输的文本就只包含这些标志名字就行,在显示的时候做对应的替换。
如:
tutuge.me
image
对应的纯文本就是:
tutuge.me[/emoji_1]
插入表情很简单,直接实例化NSTextAttachment类,将需要的表情的UIImage实例赋值给NSTextAttachment的image属性,然后用“[NSAttributedString
attributedStringWithAttachment:]”方法实例化一个NSAttributedString的对象,插入到UITextView的textStorage对应的位置即可。
如下:
这样,就能在UITextView当前光标位置插入表情图片了。
NSTextAttachment被插入到NSAttributedString中的时候,就被当成了一个字符处理!!!。
就是说,只从UITextView的text中,是找不回文本里面不同的表情所对应的标志的!
我们要能遍历出当前文本中所有的表情,也就是NSTextAttachment类。
我们要能知道遍历出的表情,对应的标志是什么。
遍历,嗯,先看看Apple有没有提供相应的方法,能遍历NSAttributedString(及其子类)的属性的。查阅文档:NSAttributedString
Class Reference,可以找到这么一个方法:“- enumerateAttribute:inRange:options:usingBlock:”,其原型如下:
用处:
看,就是这个方法~就能遍历出NSTextAttachment对象了~
如何绑定NSTextAttachment所表示的表情和与其对应的标志?创建子类嘛~直接在子类中增加属性,保存标志不就行了。
如下:
所以,这个时候,插入表情的代码应该就是下面这样:
最后,就是将这个遍历表情、拼接最终文本字符串的方法设置成NSAttributedString的自定义Category方法,以方便直接调用。
当然,这里面有些细节的处理,如替换表情标志时的字符串偏移量计算等,看代码吧。
如下:
直接调用getPlainString方法即可。
其实本文也是来源于最近的项目需求,在网上一直找不到比较好的解决方案,就自己摸索出来一个。至于复杂的图文混合编辑,当然还是Core Text来的强大(自己也在学习中)~
如果有更好地办法,一定要告诉我啊~~~
UITextView
Class Reference
NSAttributedString
Class Reference
UITextView编辑时插入自定义表情-简单的图文混编
前言
在iOS开发中,经常需要用UITextView作为编辑文本的输入控件。但是如何在编辑时插入自定义表情呢?就是像发微博时那样?
本文简单的用NSTextAttachment、NSAttributedString的特性,实现了
在UITextView中编辑文字时插入自定义表情图片
同时可以返回带有表情“替换符”的纯文本字符串。
示例
本文代码工程地址:https://github.com/zekunyan/UITextViewDIYEmojiExample效果图:
image
背景知识
NSAttributedString及其子类,用于显示富文本。NSTextAttachment,NSAttributedString的一种样式类,可以在文本中显示图片。
NSTextStorage,UITextView中的实际的文本封装。(见参考中的UITextView文档)
表情与其标志
首先需要明确的是,我们的自定义表情一定是有一一对应的“标志”的,如“[/emoji_haha]”。就是说,为了方便处理,方便在数据库、网络传输中保存、传输带有表情图片的文本,我们必须要为每种表情取特定的“名字”,数据库中储存的、网络传输的文本就只包含这些标志名字就行,在显示的时候做对应的替换。
如:
tutuge.me
image
对应的纯文本就是:
tutuge.me[/emoji_1]
插入并显示表情图片
插入表情很简单,直接实例化NSTextAttachment类,将需要的表情的UIImage实例赋值给NSTextAttachment的image属性,然后用“[NSAttributedStringattributedStringWithAttachment:]”方法实例化一个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中,是找不回文本里面不同的表情所对应的标志的!
解决点
我们要能遍历出当前文本中所有的表情,也就是NSTextAttachment类。我们要能知道遍历出的表情,对应的标志是什么。
遍历所有的NSTextAttachment类属性
遍历,嗯,先看看Apple有没有提供相应的方法,能遍历NSAttributedString(及其子类)的属性的。查阅文档:NSAttributedStringClass Reference,可以找到这么一个方法:“- enumerateAttribute:inRange:options:usingBlock:”,其原型如下:
- (void)enumerateAttribute:(NSString *)attrName inRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(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:0 usingBlock:^(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来的强大(自己也在学习中)~如果有更好地办法,一定要告诉我啊~~~
参考
UITextViewClass Reference
NSAttributedString
Class Reference
相关文章推荐
- RequireJS入门(二)
- iOS 关于UITableViewCell复用机制的理解
- 优化UITableViewCell高度计算的那些事
- iOS UITableView 修改 分区表头的样式和颜色
- RequireJS入门(一)
- Java设计模式----建造者模式(Builder)
- Java设计模式----建造者模式(Builder)
- [ios]NSThread传值 NSValue传值
- 【HDOJ】3726 Graph and Queries
- Field 'id' doesn't have a default value
- 通过NameValuePairsValueProvider对象来获取指定前缀的Key
- Java中的String类和StringBuilder类复习
- Easyui Form增加myLoad方法,使其支持二级数据对象,Fix版本
- Linguistic Data Consortium (LDC)
- druid连接池配置
- Leetcode108: Unique Binary Search Trees II
- Version和Build的区别
- NGUI坑之首行缩进
- AndroidUI-TxetView嵌套Html的使用
- UITabbar UINavigationBar