美文网首页
iOS 文字环绕题的一些探究

iOS 文字环绕题的一些探究

作者: Q14 | 来源:发表于2017-05-15 14:11 被阅读100次

    文字环绕

    想要的效果 图片为一个Button 点击查看更多或者有一个点击Acnion

    text.png

    实现方式

    1 CoreText来实现 缺点实现起来比较繁琐 像是再写底层代码
    2 textkit 来实现方便易用

    TextKit实现

    TextKit需要在 UITextView 实现
    有一下功能
    字距调整(Kerning)
    图像附件: TextView 中添加图像
    连写:


    3333.png

    段字:

    结构

    这是 UIKit 文本系统——TextKit 的简图:

    b.png

    从上图可以看出来,要让一个文本引擎工作,需要几个参与者。我们将从外到里介绍它们:

    字符串(String):NSTextStorage 保存并管理这个字符串 使用 TextKit时,NSTextStorage 就可以让文本在动态地添加字体或颜色高亮等文本属性装饰
    NSTextStorage 是一个中枢,它管理所有的文本和属性信息。系统只提供了两个存取器方法存取它们,并另外提供了两个方法来分别修改文本和属性。 NSTextStorage 是从它的父类 NSAttributedString 继承了这些方法。这就很清楚了,NSTextStorage——从文本系统看来——仅仅是一个带有属性的字符串,附带一些扩展。这两者唯一的重大不同点是 NSTextStorage 包含了一个方法,可以把所有对其内容进行的修改以通知的形式发送出来。我们等一下会介绍这部分内容。

    UITextView:在 TextKit 中,有两个目的:第一,它是文本系统用来绘制的视图。提供一个供其它类绘制的区域。作为视图层级机构中唯一的组件,第二个目的是处理所有的用户交互。具体来说,Text View 实现 UITextInput 的协议来处理键盘事件,它为用户提供了一种途径来设置一个插入点或选择文本。它并不对文本做任何实际上的改变,仅仅将这些改变请求转发给刚刚讨论的 Text Storage。

    NSTextContainer: 定义了一个文本可以绘制的区域。

    NSLayoutManager:Layout Manager 是中心组件,就是一旦textStroge有变化,通知页面布局变化,它把所有组件粘合在一起:

    1. 这个管理器监听 Text Storage 中文本或属性改变的通知,一旦接收到通知就触发布局进程。
    2. 从 Text Storage 提供的文本开始,它将所有的字符翻译为字形。
    3. 一旦字形全部生成,这个管理器向它的 Text Containers 查询文本可用以绘制的区域。
    4. 然后这些区域被行逐步填充,而行又被字形逐步填充。一旦一行填充完毕,下一行开始填充。
    5. 对于每一行,布局管理器必须考虑断行行为(放不下的单词必须移到下一行)、连字符、内联的图像附件等等。
    6. 当布局完成,文本的当前显示状态被设为无效,然后 Layout Manager 将前面几步排版好的文本设给 Text View。
      CoreText:没有直接包含在 TextKit 中,CoreText 是进行实际排版的库。对于布局管理器的每一步,CoreText 被这样或那样的方式调用。它提供了从字符到字形的翻译,用它们来填充行,以及建议断字点。
      简而言之就是

    通常由NSLayoutManager从NSTextStorage中读取出文本数据,然后根据一定的排版方式,将文本排版到NSTextContainer中,再由NSTextContainer结合UITextView将最终效果显示出来。

    实现代码

    一个简易的文字环绕

    //转化为textView内的坐标
        CGRect ovalFrame = [_textView convertRect:pathButton.bounds
                                             fromView:pathButton];
        ovalFrame.origin.x -= _textView.textContainerInset.left;
        ovalFrame.origin.y -= _textView.textContainerInset.top;
        UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect:ovalFrame];
        _textView.textContainer.exclusionPaths = @[ovalPath];//绘制路径
        _textView.textContainer.size = CGSizeMake(200, 80);//显示区域
        _textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;//文本裁切方式 ```
    实现效果 
    
    ![text.png](https://img.haomeiwen.com/i576060/fd92f53f7cebbca9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    参考
    [Objc 中国](https://objccn.io/issue-5-1/)

    相关文章

      网友评论

          本文标题:iOS 文字环绕题的一些探究

          本文链接:https://www.haomeiwen.com/subject/xvlhxxtx.html