Preface
我们在实际项目开发过程中, 常常会有这样一种需求: 文字和图片一起作为字符串显示. 常用的有微信和QQ的聊天对话框, 还有微博的发布微博信息的文本输入框. 表情和文字共存就是其中最典型的图文混排例子.
最近工作没那么忙碌, 趁着这段时间, 刚好可以写一些demo, 我弟弟也在大学学软件开发, 他的课程偏向J2EE, 但对移动开发有很强烈的兴趣. 常常叫我写一些demo, 让他学习. 所以我就答应他, 做一个仿发布微博的demo, 顺便自己用swift3.0来写, 对自己熟悉swift也有莫大的帮助.
好啦, 费话不多说...
这一次用swift来玩玩UITextView的图文混排, 好兴奋哟!
效果图:
简单说说思路:
类似Label的图文混排的方法, UITextView的图文混排当然需要用到富文本这个神奇
的东西.
富文本是个什么鬼哦?
你可以把富文本想像成色彩斑斓的文本, 可以显示不同字体大小和颜色的文字, 色彩丰富的图片, 修改字体的样式, 加入下划线等等神奇的功能, 就像魔术师一样.
text 和 attributedText
text就像素颜时候的女孩, 而attributedText就是化妆过后的美女.
所以女孩们想变得更漂亮, 就要化妆, 对应的想文本显示更有效果, 就要使用attributedText这个属性.
实现步骤:
- 生成一个图片的附件
- 创建一个富文本对象
- 设置图片的bounds
- 将图片添加到富文本上
- 把图片富文本转换成可变的富文本
- 调用富文本的对象方法 addAttributes
图片文本
- 创建NSTextAttachment的对象,用来装载图片
- 将NSTextAttachment对象的image属性设置为想要使用的图片
- 设置NSTextAttachment对象bounds大小,也就是要显示的图片的大小
- 用[NSAttributedString attributedStringWithAttachment:attch]方法,将图片添加到富文本上
下面是在微博里发表情文本的示例代码, 已经写上详细的注释:
//图片表情
//1. 生成一个图片的附件, Attachment:附件
let attachMent = NSTextAttachment()
//2. 使用NSTextAttachment将想要插入的图片作为一个字符处理,转换成NSAttributedString
attachMent.image = UIImage(named: emotion.fullPath!)
//3. 因为图片的大小是按照原图的尺寸, 所以要设置图片的bounds, 也就是大小
attachMent.bounds = CGRect(x: 0, y: -4, width: font!.lineHeight, height: font!.lineHeight)
//4. 将图片添加到富文本上
let attachString = NSAttributedString(attachment: attachMent)
//5. 把图片富文本转换成可变的富文本
let mutiAttachString = NSMutableAttributedString(attributedString: attachString)
//6. 调用富文本的对象方法 addAttributes(_ attrs: [String : Any] = [:], range: NSRange)
//来修改对应range范围中 attribute属性的 value值
//这里是修改富文本所有文本的字体大小为textView里的文本大小
mutiAttachString.addAttributes([NSFontAttributeName: font!], range: NSMakeRange(0, attachString.length))
现在已经创建好表情的富文本了, 那么可以直接赋值给textView的attributedText属性就可以显示相应的表情.
顺便附上, 插入表情或者是替换所选文本, 还有光标变化的实现代码.
// selectedRange textView的选中范围
var range = selectedRange
// attributedText textView的富文本属性
let attriText = attributedText.copy()
// 把当前textView里的富文本变成可变的富文本
let mutiAttriText = NSMutableAttributedString(attributedString: attriText as! NSAttributedString)
// 替换所选的范围(当前textView里已有的富文本替换刚插入的图片富文本)
mutiAttriText.replaceCharacters(in: range, with: attachString)
// 修改textView富文本对应范围内的字体(针对新插入的图片富文本和原来的富文本)
mutiAttriText.addAttributes([NSFontAttributeName: font!], range: NSMakeRange(0, mutiAttriText.length))
// 设置新的textView富文本
attributedText = mutiAttriText
// 光标后移一位(不管在任何位置插入一个, 或者替换图片富文本, 光标所在位置后移一位)
range.location += 1
// 没有选择任何内容
range.length = 0
// 更新当前所在的光标位置
selectedRange = range
好了, 简单的UITextView的图文混排就这样完成了.
这里有整个发布微博信息的demo, 有需要的可以下载学习:)
My github