2016-07-05 22:01:24 smaller_coder 阅读数 2285
  • 职场微技能 Word中的锦囊妙计

    本套Word2016视频教程由浅入深、循序渐进地介绍了Word2016软件安装、基础操作、文档基础排版、图文混排、表格编辑、长文档的编辑和排版、打印、综合案例及办公各个阶段经常遇到的各种锦囊妙计等等。

    3961 人正在学习 去看看 骆宝龙

在网上搜索图文混排的帖子,有好多。。大多用的第三框架,但是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. textViewAttribute = 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()

    }



2016-07-26 11:52:50 zyfmeng 阅读数 1276
  • 职场微技能 Word中的锦囊妙计

    本套Word2016视频教程由浅入深、循序渐进地介绍了Word2016软件安装、基础操作、文档基础排版、图文混排、表格编辑、长文档的编辑和排版、打印、综合案例及办公各个阶段经常遇到的各种锦囊妙计等等。

    3961 人正在学习 去看看 骆宝龙

//实现富文本
        var string:NSMutableAttributedString
        string = NSMutableAttributedString(string:"北京")
        
        //进行图文混排
        var textAttachment:NSTextAttachment
        textAttachment = NSTextAttachment()
        textAttachment.image =UIImage(named:"f_flagdown02@2x")
        textAttachment.bounds =CGRectMake(0,0,11,8);
        var textAttachmentString:NSAttributedString
        textAttachmentString = NSAttributedString(attachment: textAttachment)
//在城市名称后插入图片
        string.insertAttributedString(textAttachmentString, atIndex: string.length)
        
        //自定义导航左侧按钮
        let btn =UIButton.init(type:UIButtonType.RoundedRect)
        btn.frame =CGRectMake(0,0,70,30);
        btn.backgroundColor =UIColor.redColor()
        btn.addTarget(self, action:#selector(navBtnClick), forControlEvents: UIControlEvents.TouchUpInside)
        let lbText:UILabel
        lbText = UILabel()
        lbText.frame =CGRectMake(0,0, btn.frame.size.width+10, btn.frame.size.height)
        lbText.attributedText = string
        lbText.textColor =UIColor.whiteColor()
        lbText.font =UIFont.systemFontOfSize(13)
        btn.addSubview(lbText)
        btn.backgroundColor =UIColor.clearColor()
        self.navigationItem.leftBarButtonItem =UIBarButtonItem.init(customView: btn)


2015-10-21 22:01:34 hsf_study 阅读数 448
  • 职场微技能 Word中的锦囊妙计

    本套Word2016视频教程由浅入深、循序渐进地介绍了Word2016软件安装、基础操作、文档基础排版、图文混排、表格编辑、长文档的编辑和排版、打印、综合案例及办公各个阶段经常遇到的各种锦囊妙计等等。

    3961 人正在学习 去看看 骆宝龙
        // 从问题出发找需要的源头.
        //1.textView.attribute -> 需要 NSAttributeText ->
        //  ->replaceCharactersInRange()需要范围和图片属性 ->textView.selectedRange ->
        //   -> 由于要在光标处,输入图片而且原文本不变 ->
        //    ->需要一个NSMutableText(attributedString: textView.attributedText)
        //     ->2.建立一个NSAttributedString -> attachment:缺少一个 NSTextAttachment
        //      -> 3. 初始化一个NSTextAttachment()对象 attachment ->  4. 对象属性中有image可以做图文混排
        //
        
        let attachment =  NSTextAttachment()
        attachment.image = UIImage(contentsOfFile: emoticon.imagePath)
        
//问题二 设置苹果的高度
        let height = textView.font!.lineHeight
        // bounds 的x / y 就是scrollView的contentOffset,苹果利用bounds 的x / y 能够调整空间内部
        // 的偏移量位置
        attachment.bounds = CGRect(x: 0, y: -4, width: height, height: height)
        
//问题三 图片属性字符串,没设字体大小,导致插入图片属性高低不小
        let imageText = NSMutableAttributedString(attributedString: NSAttributedString(attachment: attachment))
        // 解决问题三,插入图片大小问题
        imageText.addAttribute(NSFontAttributeName, value: height, range: NSRange(location: 0, length: 1))
        
        let mutableText = NSMutableAttributedString(attributedString: textView.attributedText)
        mutableText.replaceCharactersInRange(textView.selectedRange, withAttributedString: imageText)
        
//问题一。记录光标
        //1). 记录光标
        let range = textView.selectedRange
        
        textView.attributedText = mutableText
        
        //2).恢复光标,同时让光标跑到原光标的位置的后一个位置(range.location + 1),同时不保留length(0)
        textView.selectedRange = NSRange(location: range.location + 1, length: 0)

tu
2016-04-07 19:58:12 Thierryxing 阅读数 74
  • 职场微技能 Word中的锦囊妙计

    本套Word2016视频教程由浅入深、循序渐进地介绍了Word2016软件安装、基础操作、文档基础排版、图文混排、表格编辑、长文档的编辑和排版、打印、综合案例及办公各个阶段经常遇到的各种锦囊妙计等等。

    3961 人正在学习 去看看 骆宝龙

用Swift写了一个Textkit图文混排Demo,类似新浪微博的头条文章编辑功能

 

实现如下功能:

 

  • 支持标题区域
  • 支持将图片作为attachment插入到文本中
  • 监听键盘事件,自动调整滚动区域
  • 自动折行,自动滚动到当前的书写区域
  • 支持输出纯文本(图片包装为img标签,可自行扩展为Json格式,方便提交到服务器端)
  • 点击图片后支持删除操作

效果如下:

 

源码地址如下:

https://github.com/thierryxing/swift-textkit-demo

 

这个版本刚刚写完,目前还有很多需要改进的地方,希望有兴趣的同学可以和我一块维护

 

2015-05-12 10:57:21 a457474875 阅读数 1267
  • 职场微技能 Word中的锦囊妙计

    本套Word2016视频教程由浅入深、循序渐进地介绍了Word2016软件安装、基础操作、文档基础排版、图文混排、表格编辑、长文档的编辑和排版、打印、综合案例及办公各个阶段经常遇到的各种锦囊妙计等等。

    3961 人正在学习 去看看 骆宝龙
//使用string 创建 NSMutableString
        var msgtext : NSMutableString = NSMutableString(string: msg.text)
        var range :NSRange = NSRange()
        var emoji : String = ""
        var locationlist : NSMutableArray = NSMutableArray()
        var location : NSDictionary = NSDictionary()
        //获取表情的位置信息和表情的具体信息带[emoji_ 及其后3位
        while msgtext.rangeOfString("[emoji_").location != NSNotFound {
            range =  msgtext.rangeOfString("[emoji_")
            if msgtext.length > (range.location  + range.length + 2){
            range = NSRange(location: range.location,length: range.length+3)
            emoji = msgtext.substringWithRange(range)
            //str.replaceCharactersInRange(aaa, withString: "")
            msgtext.replaceCharactersInRange(range, withString: "")
            location = ["loc" : range , "emoji" : emoji]
            locationlist.addObject(location)
            }else{
                break
            }
        }
        var string:NSMutableAttributedString = NSMutableAttributedString(string: msgtext as String, attributes: nil)
        
        //从后面向前依次替换表情,(从前向后的时候位置信息出现错误),10以内的补0
        for local in locationlist.reverseObjectEnumerator(){
            
            var emojilist:[String] = (local["emoji"] as! String).componentsSeparatedByString("_")
            
            let emojinum = emojilist[1]._bridgeToObjectiveC().integerValue
            println(emojinum)
            var range :NSRange = local["loc"] as! NSRange
            if  emojinum >= 10{
                var textAttachment:NSTextAttachment = NSTextAttachment(data: nil, ofType: nil)
                var smileImage:UIImage = UIImage(named: "xiaoming")!
                var picname : String = "emoji_\(emojinum)"
                smileImage = UIImage(named: picname)!
                textAttachment.image = smileImage
                var textAttachmentString:NSAttributedString  = NSAttributedString(attachment: textAttachment)
                //var range :NSRange = local["loc"] as! NSRange
                string.insertAttributedString(textAttachmentString, atIndex: range.location)
            }else if emojinum > 0{
                var textAttachment:NSTextAttachment = NSTextAttachment(data: nil, ofType: nil)
                var smileImage:UIImage = UIImage(named: "xiaoming")!
                var picname : String = "emoji_0\(emojinum)"
                smileImage = UIImage(named: picname)!
                textAttachment.image = smileImage
                var textAttachmentString:NSAttributedString  = NSAttributedString(attachment: textAttachment)
                
                string.insertAttributedString(textAttachmentString, atIndex: range.location)
            }else{
                var textAttachmentString:NSAttributedString  = NSAttributedString(string: local["emoji"] as! String)
                string.insertAttributedString(textAttachmentString, atIndex: range.location)
            }
        }

可以替换的表情格式为[emoji_01],,这样的。

最后使用

messageContentView.attributedText = string

将string放入一个textview中

简单图文混排swift

阅读数 445

没有更多推荐了,返回首页