UILabel&UITextView文本嵌入图片处理
来源:互联网 发布:淘宝网四件套100元之内 编辑:程序博客网 时间:2024/06/11 16:16
NSTextAttachment
objects are used by theNSAttributedString
class cluster as the values for attachment attributes (stored in the attributed string under the key namedNSAttachmentAttributeName
).
UILabel
下面通过例子,给UILabel的文字后面跟上一个emoji:
//创建NSTextAttachment NSTextAttachment *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中,是找不回文本里面不同的表情所对应的标志的!
解决点
- 我们要能遍历出当前文本中所有的表情,也就是NSTextAttachment类。
- 我们要能知道遍历出的表情,对应的标志是什么。
遍历所有的NSTextAttachment类属性
遍历,嗯,先看看Apple有没有提供相应的方法,能遍历NSAttributedString(及其子类)的属性的。查阅文档:NSAttributedString Class 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来的强大(自己也在学习中)~
如果有更好地办法,一定要告诉我啊~~~
参考
- 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 *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(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); //创建新的Size CGRect newSize = CGRectMake(0, 0, oriSize.width * factor, oriSize.height * factor); return newSize;}@end
使用
增加了emojiSize属性后,我们就可以在创建表情,甚至创建后,自由的调整每个NSTextAttachment的大小。
总结
一共只增加了十几行代码,但是效果还是不错哒~
- UILabel&UITextView文本嵌入图片处理
- UILabel / UITextView load HTML文本
- 利用UILabel、UITextView加载html文本
- 利用UILabel、UITextView加载html文本
- UITextView富文本、插入图片
- iOS开发笔记--UILabel和UITextView自适应文本高度代码
- iOS开发笔记--UILabel和UITextView自适应文本高度代码
- iOS之UILabel和UITextView富文本操作
- UITextView文本输入限定的处理
- UILabel 富文本 显示文字和图片
- UILabel, UITextView 高度自适应
- UILabel, UITextView 高度自适应
- UITextField,UITextView ,UILabel,键盘,UIFont
- UITextField,UITextView ,UILabel,键盘,UIFont
- UILabel和UITextView自适应高度
- UILabel、UITextView自适应得到高度
- UILabel和UITextView自适应高度
- UILabel、UITextView自适应得到高度
- What’s New In Python 3.0
- Android Vector曲折的兼容之路
- leetCode 7. Reverse Integer
- 标准容器类提供的四种迭代器类型
- 新手开发基于Django框架的python web(一)
- UILabel&UITextView文本嵌入图片处理
- python替换缺失值,处理空值+生成图形+图形标准化
- eclipse servlet 连接mysql
- VC 调用可执行程序
- IOS下微信好友和朋友圈分享实现
- hdfs编程实例
- python flask web开发 day2
- 设计模式-行为设计模式:模板方法设计模式 TemplateMethod
- 【Java技术点】JAVA操作Excel文件