目标

iOS原生的 UITextField 和 UITextView 只支持文本内容的左、中、右对齐,但是目前我的需求是需要让UITextField 和 UITextView 支持9宫格对齐方式,并能按此对齐方式进行正常输入,如下图:

目标

知识铺垫

iOS7之后,UILabel / UITextField / UITextView的实现采用TextKit进行了替换,所以对于这个命题我主要需要关注TextKit. 下面以一张图来说明TextKit内部的关键类与UITextView的逻辑关系.

TextKit类的协作

  • 说明

    • NSTextStorage 存储着文本的样式信息且是NSAttribute的子类,可以把它近似看成NSAttributeString. NSTextStorage关联一个NSLayoutManager.
    • NSLayoutManager 负责布局动作的类,把文本按其样式信息放到NSTextContainer里进行布局排版. NSLayoutManager关联一个NSTextContainer.
    • NSTextContainer 提供给NSLayoutManager用于排版的布局空,当然这肯定是根据文本信息计算出来的. 图中的黑块部分就是最终文本被填充上去的区域.
    • UITextView 以上三步都是计算的过程,从NS打头可以看出去显示无关。UITextView则提供了显示的空间,继承自UIScrollView,它包含了一个NSTextContainer用于显示以上三步计算出来的结果. 图中的黑块部分同上,蓝色部分是UITextView与NSTextContainer之间的inset,即textContainerInset .
  • 综上

    • 有了以上对TextKit与UITextView关系的初步了解后,要做到目标图中UITextView的样式,纵向上需设置textContainerInset的top和bottom,横向上需要设置UITextView的textAlignment即可。
    • UITextField要做目标图中的样式,

源码

加微博 @我是小山我是坏人

参考