我们在实际项目开发过程中, 常常会有这样一种需求: 文字和图片一起作为字符串显示. 常用的有微信和QQ的聊天对话框, 还有微博的发布微博信息的文本输入框. 表情和文字共存就是其中最典型的图文混排例子.
最近工作没那么忙碌, 趁着这段时间, 刚好可以写一些demo, 我弟弟也在大学学软件开发, 他的课程偏向J2EE, 但对移动开发有很强烈的兴趣. 常常叫我写一些demo, 让他学习. 所以我就答应他, 做一个仿发布微博的demo, 顺便自己用swift3.0来写, 对自己熟悉swift也有莫大的帮助.
好啦, 费话不多说...
这一次用swift来玩玩UITextView的图文混排, 好兴奋哟!
类似Label的图文混排的方法, UITextView的图文混排当然需要用到富文本这个神奇
的东西.
你可以把富文本想像成色彩斑斓的文本, 可以显示不同字体大小和颜色的文字, 色彩丰富的图片, 修改字体的样式, 加入下划线等等神奇的功能, 就像魔术师一样.
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, 有需要的可以下载学习:)
https://github.com/VitasLiu/WeiBoComposeDemo.git