zoukankan      html  css  js  c++  java
  • iOS开发--从TQRichTextViewDemo中学会分析project

    下载地址:

    http://code4app.com/ios/TQRichTextView/5244fe9c6803fa0862000000


    1.首先找到AppDelegate类。不管一个project有多么复杂,多么多的类。但入口仅仅有一个就是AppDelegate类的didFinishLaunchingWithOptions方法。我们阅读别人源码的时候能够从这里入手。

    在TQRichTextViewDemoproject中。这种方法中仅创建了一个TQViewController并设置为window的rootViewController。


    2.去看TQViewController的实现。

    首先也是从初始化方法開始,没有initWithNib。那么就看viewDidLoad。

    在这种方法中,仅仅创建了一个TQRichTextView,设置了frame,text。backgroundColor。delegate等属性,然后加入到了self.view上。看完viewDidLoad方法,发现这是系统调用的最后一个方法,那么结合模拟器的执行效果,我们能够推測,文字的解析和绘制过程被封装到了TQRichTextView中。


    3.去看TQRichTextView。

    1. 浏览一下头文件。了解有哪几个属性和可调用的方法。
    2. 阅读initWithFrame方法。发现这里仅仅是对几个属性的初始化。
    3. 寻找是否有重写的set,get方法。发现setText,setFont,setTextColor,setLineSpacing方法。

      阅读发现,每次更新完值后会调用setNeedsDisplay方法。说明,每次对这四个对象赋值后都会调用drawRect。

    4. 继续阅读.m文件。发现drawRect方法,这个也是有系统调用的,那么绘制的工作应该是在这里完毕。

      阅读drawRect方法。

      1. 在drawRect中首先调用了analyzeText方法,传入了參数_text。并把返回值赋给了_textAnalyzed。

        1. 去看analyzeText方法。

          首先清空了数组和字典。然后定义了一个NSString类型的result变量和NSMutableArray类型的array并赋值为richTextRunsArray。

        2. 运行TQRichTextEmojiRun的一个方法。传入string和array的指针。

          1. 由于这种方法是TQRichTextEmojiRun的类方法。全部我们直接去看该方法,而不用去看TQRichTextEmojiRun的初始化方法。连蒙带猜的我们能够确定这种方法应该是解析字符串中表情的方法。看重点。发现假设解析到表情。那么就创建一个TQRichTextEmojiRun的队形,range=表情字符串在string中的range,originalText=表情字符串,把这个创建的对象放入传进来的数组指针中。最后替换传入字符串中的表情字符串为空格,并返回被替换过表情的字符串。
          2. 通过看TQRichTextEmojiRun的init方法。发现初始化时设置了两个变量,来自父类TQRichTextBaseRun。分别设置了TQRichTextRunType和是否响应触摸。

            发现TQRichTextURLRun也继承自TQRichTextBaseRun。

          3. 跳出这种方法,回到analyzeText中,继续往下看。
        3. 运行TQRichTextURLRun的一个方法,传入result和array的指针。

          1. 同上,直接去看这种方法的实现。

            从和TQRichTextEmojiRun的命名格式类似,调用的方法名类似,我们能够推測这种方法是解析URL的,那么就直接看重点。发现,假设找到匹配的字符串。就创建一个TQRichTextURLRun的对象,设置range=URL的range,originText = URL。然后把对象加入到传进来的数组中。最后返回string。

          2. 通过看TQRichTextURLRun的init方法,发现同上初始化时设置了两个变量。来自父类TQRichTextBaseRun,分别设置了TQRichTextRunType和是否响应触摸。发现TQRichTextEmojiRun继承自TQRichTextImageRun,TQRichTextImageRun继承自TQRichTextBaseRun。
          3. 跳出这种方法,回到analyzeText中,继续往下看。
        4. 遍历richTextRunsArray中的对象,每一个对象调用setOriginalFont方法,传入參数self.font。通过阅读上面的两个方法的内部实现明确richTextRunsArray中保存的是TQRichTextEmojiRun和TQRichTextURLRun对象,所以去看这两个对象的setOriginalFont方法。

          1. 这个设置的是继承自父类TQRichTextBaseRun的属性。
          2. 回到analyzeText继续往下看。
        5. 返回result,跳出这种方法。继续看drawRect。
      2. 接下来是创建NSAttrbutedString。并赋值一些属性。
      3. 文本处理,遍历richTextRunsArray中的对象,每一个对象调用replaceTextWithAttributedString方法。

        1. 在TQRichTextEmojiRun没有找到replaceTextWithAttributedString方法。那就去TQRichTextImageRun中找。阅读该方法。

          1. 传入的attrString删除占位的空格字符。
          2. 创建CTRunDelegateCallbacks,返现设定的宽高为OriginalFont的高度的1.1倍。
          3. 创建空格NSAttrbutedString对象。加入CTRunDelegateRef属性。
          4. 把空格NSAttrbutedString对象插入至传入的attrString。
          5. 查看super方法,发如今这段range上还设置了一个键值对,key为TQRichTextAttribute,value为自己。

        2. 同上阅读TQRichTextURLRun的replaceTextWithAttributedString方法。
          1. 为该段range的文字加入蓝色字体。
          2. 调用super方法。为该段range加入同上的key-value键值对。
        3. 返回继续阅读drawRect。

      4. 以下是绘制的准备工作。不想研究咋绘制的粗读即可。
      5. 清空richTextRunRectDic
      6. 绘制,不想研究的也可粗读略过。
      7. 找重点。绘制替换过的特殊文本单元。
        1. 遍历取出每个run,取出run的attributes中key为TQRichTextAttribute的值。
        2. 假设值存在,则说明,这个run是特殊的run。
        3. 求run的frame,粗读略过。
        4. 调用drawRunWithRect方法,并将返回值赋给idDraw变量。

          1. TQRichTextEmojiRun的drawRunWithRect方法中绘制了表情图片,返回YES。
          2. TQRichTextURLRun的drawRunWithRect方法返回NO。
          3. TQRichTextBaseRun的drawRunWithRect方法返回NO。
        5. 推断run的isResponseTouch属性,查找后发现是TQRichTextBaseRun的属性,凝视说是是否响应触摸
        6. 假设响应触摸
          1. 在richTextRunRectDic中加入键值对,key为rect,value为run。
      8. 设置循环的条件。释放CF类型的变量。CF类型的变量不支持ARC。

    5. 继续寻找TQRichTextView中重载系统的方法。

      返现touchesBegan和touchesEnd方法。阅读这两个方法。

      1. 拿到触摸的点,转换点的坐标为以左下角为原点是的坐标。
      2. 推断能否仅仅想delegate
      3. 遍历richTextRunRectDic。推断点是否在rect中。假设在则调用delegate方法。
    6. 主要功能分析完成。
    7. 通读TQRichTextBaseRun。了解其他属性和一些属性的默认值。
    8. 至此,整个TQRichTextViewDemo基本分析完成。可得出例如以下结论。

      1. 类的结构关系
        1. TQRichTextEmojiRun—> TQRichTextImageRun—> TQRichTextBaseRun。

        2. TQRichTextURLRun—> TQRichTextBaseRun。
        3. TQRichTextEmojiRun和TQRichTextURLRun分别实现了analyzeText:runsArray方法用来从字符串中取出所须要的文字。并创建TQRichTextBaseRun对象加入进数组保存。
        4. TQRichTextEmojiRun和TQRichTextURLRun分别重载了replaceTextWithAttributedString方法来在字符串的特定range处加入Attributed属性。
        5. TQRichTextEmojiRun和TQRichTextURLRun分别重载了drawRunWithRect方法实现了自己定义位置,并返回是否绘制了内容。

      2. 流程
        1. 给TQRichTextView更改属性。

        2. 调用drawRect。

        3. 调用TQRichTextEmojiRun和TQRichTextURLRun的analyzeText:runsArray方法解析字符串。

        4. 创建NSAttributedString。
        5. 为NSAttributedString加入属性。
        6. 调用TQRichTextEmojiRun和TQRichTextURLRun的replaceTextWithAttributedString方法为字符串加入属性。
        7. CoreText绘制NSAttributedString。

        8. 调用TQRichTextEmojiRun和TQRichTextURLRun的drawRunWithRect方法实现自己定义绘制。
        9. 保存run和rect进字典。从字典取值推断能否点击。
      3. 有以上能够得出结论,若要更换表情和文字的解析规则。则仅仅需去TQRichTextEmojiRun或TQRichTextURLRun改动analyzeText:runsArray,replaceTextWithAttributedString,drawRunWithRect三个方法。
        1. analyzeText:runsArray改动解析规则。

        2. replaceTextWithAttributedString改动加入属性。
        3. drawRunWithRect改动自己定义绘制。
      4. 若要实现点击,仅仅需设置isResponseTouch为YES并实现TQRichTextViewDelegate。

    9. 由以上阅读代码发现例如以下缺陷
      1. TQRichTextView的awakeFromNib方法没实现。如过使用xib拖拽,则无法为TQRichTextView加入默认属性。
        1. 解决方法。加入awakeFromNib方法。并在当中为默认属性赋值。

      2. sizeWithFont和boundingRectWithSize:options:attributes:context:方法计算时不会计算行间距,TQRichTextView的lineSpacing若不设置为0会导致双方法计算的高度比TQRichTextView实际显示须要的高度小。

        1. 解决方法。TQRichTextView的lineSpacing设置为0。
  • 相关阅读:
    从零搭建hadoop集群之安装虚拟机
    数据库中的左连接和右连接的区别
    cookie 和session的区别是
    jquery获取单选按钮选中的值
    css设置背景图(背景图太大导致图片显示不全)
    vue购物车
    model修改器获取器的使用
    model时间戳自动添加
    定义路由
    模型使用:M模型 V视图 C控制
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6801699.html
Copyright © 2011-2022 走看看