二.cocoa touch 之 TextKit

来源:互联网 发布:什么是棋牌源码 编辑:程序博客网 时间:2024/06/05 15:14

     在程序中,通过Text Kit可以对文字进行存储(store)、布局(lay out),以及用最精细的排版方式(例如文字间距、换行和对齐等)来显示文本内容。 苹果引入Text Kit的目的并非要取代已有的Core Text,Core Text的主要作用也是用于文字的排版和渲染中,它是一种先进而又处于底层技术,如果我们需要将文本内容直接渲染到图形上下文(Graphics context)时,从性能和易用性来考虑,最佳方案就是使用Core Text。而如果我们直接利用苹果提供的一些控件(例如UITextView、UILabel和UITextField等)对文字进行排版,无疑就是借助于UIkit framework中Text Kit提供的API。

Text Kit架构

下面,我们通过图1(此图来自WWDC2013 Session 210)来了解一下Text Kit的架构。下图(图1)是基于iOS 7绘制的,从图中,我们可以看到Text Kit是基于Core Text构建的,它通过Core Text与Core Graphics进行交互。而UI控件(UILabel、UITextField和UITextView)则构建于Text Kit之上,可见这些文本控件可以利用Text Kit提供的API来对文字进行排版和渲染处理。 从图中我们也可以看到SDK提供的UIWebView是基于WebKit的,它不能使用Text Kit提供的功能。


我们再来看看图1中的相关组件在iOS6里面是如何对应的,如图2(下图)所示,可以看出在iOS 6中是没有Text Kit,并且UILabel、UIText和UITextView是基于String Drawing和WebKit构建的。其中String Drawing是与Core Graphics直接通讯。


Text Kit中主要有4个重要的对象。

  • Text View是用来显示文本内容的控件,主要包括UILabel、UITextView和UITextField。
  • Text containers对应着NSTextContainer类。NSTextContainer定义了文本可以排版的区域。一般来说,都是矩形区域,当然,也可以根据需求,通过子类化NSTextContainer来创建别的一些形状,例如圆形、不规则的形状等。NSTextContainer不仅可以创建文本可以填充的区域,它还维护着一个数组——该数组定义了一个区域,排版的时候文字不会填充该区域,因此,我们可以在排版文字的时候,填充非文本元素。
  • Layout manager对应着NSLayoutManager类。该类负责对文字进行编辑排版处理——通过将存储在NSTextStorage中的数据转换为可以在视图控件中显示的文本内容,并把统一的字符编码映射到对应的字形(glyphs)上,然后将字形排版到NSTextContainer定义的区域中。
  • Text storage对应着NSTextStorage类。该类定义了Text Kit扩展文本处理系统中的基本存储机制。NSTextStorage继承自NSmutableAttributedString,主要用来存储文本的字符和相关属性。另外,当NSTextStorage中的字符或属性发生了改变,会通知NSLayoutManager,进而做到文本内容的显示更新。

通常情况下,NSTextStorage、NSLayoutManager和NSTextContainer是一一对应的。如下图所示关系:


通常,我们在设备上只能看到最右边的文本显示界面,而内部的NSTextStorage、NSLayoutManager和NSTextContainer是看不出来的。通常由NSLayoutManager从NSTextStorage中读取出文本数据,然后根据一定的排版方式,将文本排版到NSTextContainer中,再由NSTextContainer结合UITextView将最终效果显示出来。


Text Kit示例

//更新textview排版

- (void)updateExclusionPaths{

   CGRect butterflyImageRect = [self.textViewconvertRect:self.imageView.framefromView:self.textView];

   UIBezierPath *newButterflyPath = [UIBezierPathbezierPathWithRect:butterflyImageRect];

    self.textView.textContainer.exclusionPaths =@[newButterflyPath];

    [selfupdateClippy];

}

//storage 和 layoutmanager 、container 结合使用

    textStorage = [LCLARCTextStoragenew];

   NSLayoutManager *layoutManager = [LCLTextLayoutManagernew];

    layoutManager.delegate =self;

    [textStorageaddLayoutManager:layoutManager];

    NSTextContainer *textContainer = [[NSTextContaineralloc] initWithSize: CGSizeZero];

    [layoutManageraddTextContainer: textContainer];

   self.textView = [[UITextViewalloc] initWithFrame:self.view.boundstextContainer: textContainer];

   self.textView.delegate =self;

    [self.textViewsetEditable:NO];

    self.textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    self.textView.translatesAutoresizingMaskIntoConstraints = YES;

    self.textView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

    [self.viewaddSubview:self.textView];

    [self.textViewaddSubview:self.imageView];

    [self.textViewaddSubview:self.clipyImageView];

//    [textStorage addLayoutManager:self.textView.layoutManager];

    [textStoragereplaceCharactersInRange:NSMakeRange(0,0) withString:str];

//    [self.textView.textStorage replaceCharactersInRange:NSMakeRange(0, 0) withString:str];

    self.textView.layoutManager.hyphenationFactor = 1.0;

    [selfupdateExclusionPaths];




0 0
原创粉丝点击