zoukankan      html  css  js  c++  java
  • 浅析微博编辑页面图文混排中遇到的问题

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

    上期回顾:关于微博编辑页面添加表情键盘 

    如果你不是在董铂然博客园看到本文,请点击查看原文

    1.默认每添加一个表情是添加到最后,但是我们想添加到光标位置

    默认做法(其中的str是通过点击某个表情通过代理传来的表情字符串)

    //         会把用户选择的表情,拼接到最后!
                textView.text = textView.text + (str ?? "")!
    

     如果想插入到光标位置

                // 在用户光标位置插入表情文本
                textView.replaceRange(textView.selectedTextRange!, withText: str!)

     

    2.添加后的图标大小不一样。

    解决方法:给所有的range设置一个统一的格式

               // 设置整个属性字符串中的文本属性
                let range = NSMakeRange(0, strM.length)
                // 让 可变的属性文本 的字体 和 textView 的保持一致!
                strM.addAttribute(NSFontAttributeName, value: textView.font, range: range)    
    

    3.因为前面用的是替换文本,所以在中间插入表情之后,光标会跳到段落末尾

    解决方法:提前记录光标的位置,然后在替换完文本位置之后再复原光标位置

    在恢复光标的时候应该是location+1,如果不加1就是插入后光标在表情的前面

                // 记录光标位置 location 对应光标的位置
                var location = textView.selectedRange.location
                // 直接替换文本结果会导致光标移动到文本末尾
                textView.attributedText =  strM
                // 重新设置光标位置
                textView.selectedRange = NSMakeRange(location + 1, 0)

    4.但是textView里显示的是textView.AttrubuteText。富文本是对象无法直接发送出去。

    解决方法:

    ①首先在每次点击表情时把textView.AttrubuteText 打印出来 可以看到大批量的打印,输出的是字典。区分后可以看出如果是表情,在字典里有NSAttachment的键值。而文本没有

    ②通过以上那点的区别,遍历这个大批量打印,打印出dict和Range,把所有的文本和表情都区分开

    打印是:

    ③利用这个思路,写一个textAttrubute的子类,并在这个方法中给表情对应的文本符号赋值,以后后来取用

    import UIKit
    
    class SXEmoteTextAttachment: NSTextAttachment {
        // 表情对应的文本符号
        var emoteString: String?
        
        /// 返回一个 属性字符串
        class func attributeString(emoticon: Emoticon, height: CGFloat) -> NSAttributedString {
            var attachment = SXEmoteTextAttachment()
            attachment.image = UIImage(contentsOfFile: emoticon.imagePath!)
            attachment.emoteString = emoticon.chs
            
            // 设置高度
            attachment.bounds = CGRectMake(0, -4, height, height)
            
            // 2. 带图像的属性文本
            return NSAttributedString(attachment: attachment)
        }
    }

    ④在点击某个图片时,调用方法返回一个属性字符串 ,在这一句调用.attributeString时已自动将表情转化成文本符号

            var attributeString = SXEmoteTextAttachment.attributeString(emoticon, height: font.lineHeight)

    ⑤定义一个result用于记录拼接后的字符串

        /// 返回文本框中转换完成后的字符串 - (将表情图片转换成表情符号)
        func fullText() -> String {
            var result = String()
            let textRange = NSMakeRange(0, attributedText.length)
            
            attributedText.enumerateAttributesInRange(textRange, options: NSAttributedStringEnumerationOptions.allZeros, usingBlock: { (dict, range, _) -> Void in
                
                if let attachment = dict["NSAttachment"] as? SXEmoteTextAttachment {
                    // 图片
                    result += attachment.emoteString!
                } else {
                    result += (self.attributedText.string as NSString).substringWithRange(range)
                }
            })
            println("微博文本:(result)")
            return result
        }
    

     ⑥最后就是在发微博的时候修改下参数,不是发textView.AttrubuteText 也不是发textView.text .而是发拼接后的

        /// 发微博
        @IBAction func sendStatus(sender: UIBarButtonItem) {
            let urlString = "https://api.weibo.com/2/statuses/update.json"
            
            if let token = AccessToken.loadAccessToken()?.access_token{
                // 这里调用fullText方法 返回记录并拼接后的
                let params = ["access_token":token,"status":textView.fullText()]
                
                let net = NetworkManager.sharedManager
                
                net.requestJSON(.POST, urlString, params){ (result, error) -> () in
                    SVProgressHUD.showInfoWithStatus("微博发送成功")
                    self.dismissViewControllerAnimated(true, completion: nil)
                }
            }
        }
    

     ⑦到此就完成了,编辑微博内显示,和发送微博时的文本分开治理,互不冲突。

    5.取消发布时,撰写微博控制器快速就缩回了,回到了首页键盘才缓慢缩回。

    解决方法:

        /// 取消按钮点击事件
        @IBAction func cancel(sender: UIBarButtonItem) {
            
            /// 为了更好的用户体验先缩键盘再缩文本框
            self.textView.resignFirstResponder()
            dismissViewControllerAnimated(true, completion: nil)
        }
    

    6.在输入框中,表情和文字在水平方向上并不是对齐状态,上下有差值

    解决方法:微调

                let height = textView.font.lineHeight
                attachment.bounds = CGRectMake(0, -4, height, height)
    

    7.只有在输入文字时,placeholder和发送按钮才会隐藏和点亮。点击插入图片时没有反应

    解决方法:手动让用户在输入图片时也调用代理方法

    在图片点击代理方法emoticonsViewControllerDidSelectEmoticon里

            // 手动调用代理方法 - 是否能够插入文本
            if textView(textView, shouldChangeTextInRange: textView.selectedRange, replacementText: str!) {
                /// 设置输入框的文字
                if emoticon.chs != nil {
                    /// 从分类的方法中取
                    textView.setTextEmoticon(emoticon)
                    // 手动调用 didChage 方法
                    textViewDidChange(textView)
                    
                }else if emoticon.emoji != nil {
                    /// 默认是把表情拼接到最后, 用这行代码是在光标位置插入文本
                    textView.replaceRange(textView.selectedTextRange!, withText: emoticon.emoji!)
                }
            }
    

     其中的textViewDidChange 是用来控制按钮状态

        func textViewDidChange(textView: UITextView) {
            let fullText = self.textView.fullText()
            
            self.textView.placeHolderLabel!.hidden = !fullText.isEmpty
            sendButton.enabled = !fullText.isEmpty
        }
    

    8.在控制最大输入数时一个表情如“[花心]” 占了8个字节

    原来是

            // 微博文字通常限制 140 个字
            if textView.text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) + text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 140 {
                return false
            }
    

    改成

            // 微博文字通常限制 140 个字
            if (self.textView.fullText() as NSString).length + (text as NSString).length > 140 {
                return false
            }
    

    如果你不是在董铂然博客园看到本文,请点击查看原文

     欢迎关注!

  • 相关阅读:
    bzoj 1057: [ZJOI2007]棋盘制作
    【NOIP2012】开车旅行
    bzoj 2326: [HNOI2011]数学作业
    一本通1527欧拉回路
    一本通1530 Ant Trip
    一本通1528单词游戏
    luogu1856
    CF1045G
    10.18模拟赛
    10.16模拟赛
  • 原文地址:https://www.cnblogs.com/dsxniubility/p/4343104.html
Copyright © 2011-2022 走看看