iOS开发 - UITextView的图文混排

rxjk0436 8年前
   <p>我们在实际项目开发过程中, 常常会有这样一种需求: 文字和图片一起作为字符串显示. 常用的有微信和QQ的聊天对话框, 还有微博的发布微博信息的文本输入框. 表情和文字共存就是其中最典型的图文混排例子.</p>    <p>最近工作没那么忙碌, 趁着这段时间, 刚好可以写一些demo, 我弟弟也在大学学软件开发, 他的课程偏向J2EE, 但对移动开发有很强烈的兴趣. 常常叫我写一些demo, 让他学习. 所以我就答应他, 做一个仿发布微博的demo, 顺便自己用swift3.0来写, 对自己熟悉swift也有莫大的帮助.</p>    <p>好啦, 费话不多说...</p>    <p>这一次用swift来玩玩UITextView的图文混排, 好兴奋哟!</p>    <p>简单说说思路:</p>    <p>类似Label的图文混排的方法, UITextView的图文混排当然需要用到富文本这个 神奇 的东西.</p>    <h2>富文本是个什么鬼哦?</h2>    <p>你可以把富文本想像成色彩斑斓的文本, 可以显示不同字体大小和颜色的文字, 色彩丰富的图片, 修改字体的样式, 加入下划线等等神奇的功能, 就像魔术师一样.</p>    <p>text 和attributedText</p>    <p>text就像素颜时候的女孩, 而attributedText就是化妆过后的美女.</p>    <p>所以女孩们想变得更漂亮, 就要化妆, 对应的想文本显示更有效果, 就要使用attributedText这个属性.</p>    <h2>实现步骤:</h2>    <ul>     <li> <p>生成一个图片的附件</p> </li>     <li> <p>创建一个富文本对象</p> </li>     <li> <p>设置图片的bounds</p> </li>     <li> <p>将图片添加到富文本上</p> </li>     <li> <p>把图片富文本转换成可变的富文本</p> </li>     <li> <p>调用富文本的对象方法 addAttributes</p> </li>    </ul>    <h3>图片文本</h3>    <ol>     <li> <p>创建 <strong>NSTextAttachment</strong> 的对象,用来装载图片</p> </li>     <li> <p>将 <strong>NSTextAttachment</strong> 对象的 <strong>image</strong> 属性设置为想要使用的图片</p> </li>     <li> <p>设置 <strong>NSTextAttachment</strong> 对象 <strong>bounds</strong> 大小,也就是要显示的图片的大小</p> </li>     <li> <p>用 [NSAttributedString attributedStringWithAttachment:attch] 方法,将图片添加到富文本上</p> </li>    </ol>    <p>下面是在微博里发表情文本的示例代码, 已经写上详细的注释:</p>    <pre>  <code class="language-objectivec">//图片表情  //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))</code></pre>    <p>现在已经创建好表情的富文本了, 那么可以直接赋值给textView的attributedText属性就可以显示相应的表情.</p>    <p>顺便附上, 插入表情或者是替换所选文本, 还有光标变化的实现代码.</p>    <pre>  <code class="language-objectivec">// 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</code></pre>    <p>好了, 简单的UITextView的图文混排就这样完成了.</p>    <p> </p>    <p>来自:http://www.cocoachina.com/ios/20161207/18311.html</p>    <p> </p>