在网上搜索图文混排的帖子,有好多。。大多用的第三框架,但是swift实现图文混排的帖子还真不多,我在这里和大家一起梳理一下。希望彼此都能有所帮助,

废话不多说,进入正题:

首先我们都知道,图文混排主要是用在UITextView/ UILab / UITextFiled 等能够输入或者显现表情与文字的控件中,主要用到的属性是NSAttributeText,因此,我们基本上可以把图文混排分为三部分内容

1. 表情键盘的创建(将表情包中的表情添加到键盘上)

2. 点击表情时,表情能够与文字同时显示到输入框上

3. 可以上传到服务器,并且在前端显示出来

现在我们就开始分别总结一下这三点:

1. 表情键盘的创建

首先是表情源的获取,基本上是一个NSBundle文件,里面装几个表情文件夹,我们获取到每一个图片,然后赋值到表情键盘的button上,表情键盘的实质也就是一个UICollectionView,每个cell上放了若干了button,这一部分比较简单。我们就不做过多的赘述,有兴趣的同学可以直接看代码<EmoticonView.swift>

2. 表情键盘显示到输入框

//通过点击表情按钮,发送通知,将button传递过来,里面包含了自身的表情模型

 let imageName = "\(path)/\(png)"
        // 创建NSMutableAttributedString对象
        let attributeMutableString = NSMutableAttributedString(attributedString: textV.attributedText)
        let textAttachment = NSTextAttachment()
        //设置textAttachment的大小和属性
        textAttachment.bounds = CGRectMake(0, -5, (textV.font!.lineHeight), textV.font!.lineHeight)
       
        //获取当前的光标位置
        textAttachment.image = UIImage(named: imageName)
   
        let attributeString = NSAttributedString(attachment: textAttachment)
       
        //设置位置,替换
        let range =  textV.selectedRange
       
        attributeMutableString.replaceCharactersInRange(range, withAttributedString: attributeString)

attributeMutableString.addAttributes([NSFontAttributeName: textV.font!], range: NSMakeRange(0, attributeMutableString.length))
       
       
        //MARK:设置表情的大小
        textV.attributedText = attributeMutableString
       
        //让光标回到下一个位置
        textV.selectedRange = NSMakeRange(range.location + 1, 0)
       
        }
       
        if let emoji = emoticon?.emoji {
       
            textV.replaceRange(textV.selectedTextRange!, withText: emoji)

}

3. 表情文本的上传到服务器,首先我们要清楚一下,发布到服务器都必须是字符串形式,这就需要我们在上传之前,将textView的attributeText全部转化为字符串,

func transformToString () ->String {
       
var publishString: String= String()
       
        self.attributedText.enumerateAttributesInRange(NSMakeRange(0,self.attributedText.length), options: []) { (data, range, _) -> Void in
           
                iflet dataDict = data as? [String: AnyObject] {
               
            if let attachment = dataDict["NSAttachment"] {

                   
                   
             //将attachment强制转为YDTextAttachment
               let YDattachment = attachment as! YDTextAttachment
         
                    //将表情转为文字,需要在NSAttachment里面有emoticon模型
                publishString = publishString + (YDattachment.emoticon?.chs)!
                   
                   
                }else{
  
                    //将self.textV.text按照范围进行切割
                    print(range)
                   
                    let subString = (self.textas NSString).substringWithRange(range)
   
                    publishString = publishString + subString
                   
                   
                }
               
            }
    }
   
        return publishString
    }

最后就是从服务器获取到的有表情的text在前端的展示,这块用到了正则表达式, 里面用到了两个方法

class func getAttributeString(emoticon:HMEmoticon? ,font: UIFont) -> NSAttributedString? {

// 1. 创建一个附件对象

let attachment = HMTextAttachment()

// 1.1 拼接图片路径

guard let path = emoticon?.path,png = emoticon?.png else {

return nil

}

let imagePath = "\(path)/\(png)"

// 1.2 设置他的属性

attachment.image = UIImage(named: imagePath)

// 1.3 修改图片的bounds

// 思考表情的宽高怎么设置?

let lineHeght = font.lineHeight

attachment.bounds = CGRectMake(0,-5, lineHeght, lineHeght)

// 2. 创建一个NSAttributeString对象

let attribute = NSAttributedString(attachment: attachment)

return attribute

}

 private func dealEmoticonText(text: String?) -> NSAttributedString {

guard let text = text else  {

return NSAttributedString()

}

// 定义一个 全局AttributeString

let globleAttribute = NSMutableAttributedString(string: text)

// 1. 把表情的对象HMEmotion,发送给了 HMPublishViewController

// 2. 创建了一个NSAttributeString, 拥有一个附件.NStextAttachment, image

// 3. textView的Attribute = attribute

/*

text -- 微博内容含有表情的情况有多种

1.没有表情

2.有一个表情 -> [微笑]

3.有多个表情

*/

// I [嘻嘻] U

/*

. 匹配任意字符,除了换行

() 锁定要查找的内容

* 匹配任意长度的内容

?尽量少的匹配

\\[.*?\\]

*/

// 分析正则为主

let pattern = "\\[.*?\\]"

/*

默认的try

try?

try!

*/

do {

/*

第一个参数: 正则表达式

第二个参数: 针对正则表达式的一些设置, 不要刻意去记,学一个记一个

*/

// 1. 创建正则

let regx = try NSRegularExpression(pattern: pattern, options: .DotMatchesLineSeparators)

// 2. 让正则去匹配查找

/*

第一个参数: 指定查找的字符串

第二个参数: 默认值

第三个参数: 范围

*/

let results =  regx.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count))

// 3. 就是对 查找结果进行遍历

//  NSTextCheckingResult

for (_,result) in results.reverse().enumerate() {

// 获取查找结果的range

let range = result.range

// 通过range来获取查找的表情字符串

let emoticonString = (text as NSString).substringWithRange(range)

// 通过表情字符串,转换成表情对象

let emoticon = HMEmoticonManager.searchEmoticon(emoticonString)

let attachment = HMTextAttachment()

attachment.emoticon = emoticon

let attribute = attachment.getAttributeString(UIFont.systemFontOfSize(16))

// 通过类方法,可以变成一行代码

let attribute2 = HMTextAttachment.getAttributeString(emoticon, font: UIFont.systemFontOfSize(16))

// globleAttribute = I  U

// 进行一个替换

globleAttribute.replaceCharactersInRange(range, withAttributedString: attribute!)

}

/* 第一次打印还没有进行替换: I [嘻嘻] [嘻嘻] U{

}

~~~~~~~~~~~~~~~~~

第二次打印

I {

}{

NSAttachment = "<NSTextAttachment: 0x7fbd787f9c00>";

} [嘻嘻] U{

}

*/

// 遍历结束之后,再返回

return globleAttribute

} catch {

printLog(error)

}

return NSAttributedString()

}

SWIFT实现图文混排相关推荐

  1. [Swift通天遁地]八、媒体与动画-(13)CoreText框架实现图文混排

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  2. ios 表情符号 键盘_iOS 表情键盘+gif聊天图文混排,看我的就够了

    更新: 1.解决首次加载键盘卡顿的问题: 2.修改聊天布局方式,现在无需计算,更加丝滑. 前言: 之前做过[OC版本]和[swift版本]图文混排和表情键盘,说实在的很low,特别是键盘,整体只是实现 ...

  3. 浅析微博编辑页面图文混排中遇到的问题

    在表情键盘的图文混排中,会有很多细节问题.有的时候不理解其中的原因是很难改正的.本文主要是整理我遇到的各种问题及解决方案,供大家分享.如果你以前也遇到过类似的问题可以用我的方法修正了,希望能够对博友们 ...

  4. android多媒体图文混排,干货!!!Android富文本实现图文混排

    效果图 rich.jpg 像图中的效果,大家在开发并不少见,大家可能不知道android提供了实现图文混排的类.大家或许会写一个布局或者使用drawableLeft这个属性实现文本的左侧图标. and ...

  5. iOS - 图文混排技术方案分享

    前言 不少同学在工作中都能遇到图文混排的需求.但是实现图文混排的技术方案有好几种,相应的方案优劣也有差别.今天和大家一起分享一下图文混排的技术方案以及我的选择. Demo和解析工具已经开源 GitHu ...

  6. Android TextView中图文混排设置行间距导致高度不一致问题解决

    Android TextView中图文混排设置行间距导致高度不一致问题解决 参考文章: (1)Android TextView中图文混排设置行间距导致高度不一致问题解决 (2)https://www. ...

  7. android富文本图片自适应,Android Span富文本图文混排 - ImageSpan(图文垂直居中)...

    ###为文字实现很丰富的特殊效果,当然少不了图文混排 so... 直接上效果(有直接使用和自定义垂直居中效果) ##1 ImageSpan: ImageSpan(context, resourceId ...

  8. TextView图文混排,显示添加的图片,三种常用方法,亲测

    图文混排,文字就不说了,主要是显示图片的方法 1.TextView使用ImageSpan显示图片 [java] view plaincopy <span style="font-siz ...

  9. 利用ListView实现新闻客户端的新闻内容图文混排

    如图: 布局文件: <LinearLayout xmlns:android="<a href="http://schemas.android.com/apk/res/a ...

最新文章

  1. db9针232接口波特率标准_RS232和RS485与RS422接口的基础知识详细介绍
  2. getRunningTasks和getRunningAppProcesses失效
  3. 牛客java面试题总结版(三)
  4. 跨站点请求伪造(CSRF)总结和防御
  5. 一次基于Vue.Js的用户体验优化 (vue drag)
  6. mapbox 导航_狂甩不掉,骑行最稳手机支架!一体式安装太方便,秒变单车导航仪...
  7. OC-NSFileManager和NSFileHandle的使用
  8. lin通信ldf文件解析_lin ldf
  9. 移动端开发meta标签 viewport 设置
  10. centos 安装mysql5.6.20_Linux学习15-CentOS安装mysql5.6环境
  11. 矩阵方程的计算求解(Matlab实现)
  12. 排序算法系列之(二)——冒泡排序名字最为形象的一个
  13. 龙芯(Loongarch64),在Linux虚拟一个龙芯OS体验下
  14. 文档转换 云服务器,文档转换服务
  15. 启xin宝app的token算法破解
  16. 课后作业week 5 —— 两款修图软件优势及创新分析
  17. random seed什么意思
  18. python3-爬取cnnvd漏洞信息-代理+多线程
  19. 【杂篇】书单(技术、文学、历史、经济、方法论等等)
  20. TCP/IP网络编程 学习笔记_13 --基于I/O复用的服务端

热门文章

  1. 飞机大战python介绍_用 Python 写一个经典飞机大战
  2. Tableau数据分析-Chapter10 人口金字塔、漏斗图、箱线图
  3. 2022年信息系统运行管理员考试大纲
  4. 无源晶振匹配电容计算公式
  5. 教你用RNN实现人工智能写作
  6. Gavin老师Transformer直播课感悟 - Rasa对话机器人项目实战之教育领域Education Bot项目NLU Data详解(七十一)
  7. 晋升述职,你真的准备好了吗?
  8. 四国军棋界面开发(5)吃子规则与声音效果
  9. 【软件工程习题(含参考答案)】面向对象章节
  10. Arduino 流水灯 从右往左亮起来,再从左往右亮起来