底层文本处理技能

大多数运用程序能够运用高档文本显现类和Text Kit来处理一切文本。但是,您可能有一个运用程序需求运用来自Core Text、Core Graphics和Core Animation结构以及其他UIKit API的低等级编程接口。

简略的文本制作(Simple Text Drawing)

除了用于显现和修正文本的UIKit类之外,iOS还包括几种直接在屏幕上制作文本的办法。制作简略字符串最简略、最有用的办法是运用UIKit对NSString类的扩展,该类坐落名为UIStringDrawing的类别中。这些扩展包括运用各种特点在屏幕上任意方位制作字符串的办法。还有一些办法能够在实践制作之前核算烘托字符串的大小,这能够帮助您更准确地布局运用程序内容。

重要提示:有一些很好的理由能够防止直接制作文本,而倾向于运用UIKit结构的文本方针。一个是功用。尽管UILabel方针也制作其静态文本,但它只制作一次,而文本制作例程通常会被重复调用。文本方针还供给了更多的交互;例如,它们是可挑选的。

UIStringDrawing的办法在给定的点(关于单行文本)或指定的矩形内(关于多行文本)制作字符串。您能够传入制作时运用的特点,例如字体、换行形式和基线调整。UIStringDrawing的办法答应您准确调整烘托文本的方位,并将其与视图的其他内容混合。它们还答应您根据所需的字体和款式特点提早核算文本的鸿沟矩形。

您还能够运用Core Animation的CATextLayer类来进行简略的文本制作。这个类的方针存储一个一般字符串(plain string)或特点字符串(attributed string)作为其内容,并供给一组影响该内容的特点,如字体、字体大小、文本色彩和截断行为。CATextLayer的优点是(作为CALayer的子类)其特点本质上能够做动画。Core Animation与QuartzCore结构相关联。因为CATextLayer的实例知道怎么在当时的图形上下文中制作自己,所以在运用这些实例时,您不需求宣布任何明确的制作指令。

有关NSString的字符串制作扩展的信息,请参阅NSString UIKit Additions Reference。要了解有关CATextLayer、CALayer和Core Animation其他类的更多信息,请参阅Core Animation Programming Guide。

Core Text

Core Text是一种用于自界说文本布局和字体办理的技能。运用程序开发人员通常不需求直接运用Core Text。Text Kit建立在Core Text之上,具有相同的优势,例如速度和杂乱的排版功用。此外,Text Kit供给了很多的基础设施,假如您运用Core Text,则需求自己构建这些基础设施。

但是,关于有必要直接运用它的开发人员来说,Core Text API是可拜访的。它旨在由具有自己布局引擎的运用程序运用——例如,具有自己页面布局引擎的文字处理器能够运用Core Text生成字形并将它们放在对的方位。

Core Text作为一个结构完成,发布了一个类似于Core Foundation的API——类似之处在于它是过程式的(ANSI C),但根据类似方针的不透明类型。该API与Core Foundation和Core Graphics都进行了集成。例如,Core Text在许多输入和输出参数中运用Core Foundation和Core Graphics方针。此外,因为许多Core Foundation方针与Foundation结构中的对应方针是“免费桥接”的,因而您能够在Core Text函数的参数中运用这些Foundation方针。

注意:假如您运用Core Text或Core Graphics制作文本,请记住,您有必要对当时文本矩阵运用翻转改换,以使文本以其正确的方向显现——也就是说,绘图原点坐落字符串鸿沟框的左上角。
Core Text有两个首要部分:布局引擎和字体技能,每个部分都有自己的不透明类型集合支撑。

Core Text布局不透明类型(Core Text Layout Opaque Types)

Core Text需求两个不透明类型不是它自身的方针:一个特点字符串(CFAttributedStringRef)和一个图形途径(CGPathRef)。特点字符串方针封装了显现的字符串,并包括界说字符串中字符的款式方面的特点——例如,字体和色彩。图形途径界说了a frame of text的形状,相当于一个阶段。

运转时,Core Text方针形成一个层次结构,这个结构反映了处理的层级(见图9-1)。在这个层次的顶部是framesetter方针(CTFramesetterRef)。framesetter运用特点字符串和图形途径作为输入,生成一个或多个文本frame(CTFrameRef)。文本在frame中布局时,framesetter将阶段款式运用于它,包括对齐、制表符、行间距、缩进和换行形式等。

为了生成frame,framesetter会调用一个 typesetter 方针(CTTypesetterRef)。typesetter方针将特点字符串中的字符转换为字形,并将这些字形填充到行中。(字形是用于表明字符的图形形状。)结构中的一行由CTLine方针(CTLineRef)表明。CTFrame方针包括一个CTLine方针的数组。

反过来,CTLine方针包括一个由CTRunRef类型的方针表明的字形runs的数组。字形runs是具有相同特点和方向的接连字形的序列。尽管排版方针回来CTLine方针,但它运用字形运转的数组来组合这些行。

Figure 9-1Core Text layout objects

Text Programming Guide for iOS - 10 - Lower Level Text-Handling Technologies

运用CTLine不透明类型的函数,您能够从特点字符串中制作一行文本,而无需经过CTFramesetter方针。您只需将文本的原点定位在文本基线上,并请求行方针自行制作。

译者注:这段的意思是,CTFrame包括一系列CTLine,一个CTLines包括一系列CTRun,一个CTRun包括一系列具有相同特点和方向的接连字形

Core Text字体不透明类型

字体关于Core Text中的文本处理至关重要。typesetter方针运用fonts(从特点字符串取得的特点)将字符转换成字形,然后排这些字形的相对方位。图形上下文关于Core Text中的字体至关重要。您能够运用图形上下文函数来设置当时字体并制作字形;或许,您能够从特点字符串创建一个CTLine方针,并运用其函数在图形上下文中进行制作。Core Text字体体系原生处理Unicode字体。

The font system includes objects of three opaque types:CTFont,CTFontDescriptor, andCTFontCollection:

  • Font objects (CTFontRef) are initialized with a point size and specific characteristics (from a transformation matrix). You can query the font object for its character-to-glyph mapping, its encoding, glyph data, and metrics such as ascent, leading, and so on. Core Text also offers an automatic font-substitution mechanism called font cascading.
  • Font descriptor objects (CTFontDescriptorRef) are typically used to create font objects. Instead of dealing with a complex transformation matrix, they allow you to specify a dictionary of font attributes that include such properties as PostScript name, font family and style, and traits (for example, bold or italic).
  • Font collection objects (CTFontCollectionRef) are groups of font descriptors that provide services such as font enumeration and access to global and custom font collections.

It’s possible to convertUIFontobjects toCTFontobjects by callingCTFontCreateWithName, passing the font name and point size encapsulated by theUIFontobject.

Core Graphics文本制作

Core Graphics(或Quartz)是处理二维图画的体系结构,坐落最低等级。文本制作是其功用之一。一般来说,因为Core Graphics的等级很低,因而主张您运用体系的其他技能来制作文本。但是,假如状况需求,您能够运用Core Graphics制作文本。

您能够运用CGContext不透明类型的函数挑选字体、设置文本特点并制作文本。例如,您能够调用CGContextSelectFont来设置所运用的字体,然后调用CGContextSetFillColor来设置文本色彩。然后,您设置文本矩阵(CGContextSetTextMatrix)并运用CGContextShowGlyphsAtPoint制作文本。

有关这些函数及其运用的更多信息,请参阅Quartz 2D Programming Guide和Core Graphics Framework Reference。

Foundation等级的正则表达式

Foundation结构的NSString类包括一个简略的程序接口来处理正则表达式。您调用三个办法中的一个,该办法回来一个规模,传递一个特定的选项常量和一个正则表达式字符串。假如有匹配项,则该办法回来子字符串的规模。选项是NSRegularExpressionSearch常量,它是位掩码类型的NSStringCompareOptions;这个常量告知该办法希望一个正则表达式形式,而不是一个字面字符串作为搜索值。支撑的正则表达式语法是由ICU(世界Unicode组件)界说的。

注意:除了这里描绘的NSString正则表达式特性外,iOS还经过NSRegularExpression类供给了更完好的正则表达式支撑。ICU用户攻略描绘了怎么构建ICU正则表达式(userguide.icu-project.org/strings/reg…

NSString的正则表达式办法如下:

rangeOfString:options:
rangeOfString:options:range:
rangeOfString:options:range:locale:
假如您在这些办法中指定了NSRegularExpressionSearch选项,那么您能够指定的其他NSStringCompareOptions选项只要NSCaseInsensitiveSearch和NSAnchoredSearch。假如正则表达式搜索未找到匹配项或正则表达式语法不正确,则这些办法回来一个NSRange结构,其值为{NSNotFound, 0}。

清单9-1给出了运用NSString正则表达式API的示例。

Listing 9-1 Finding a substring using a regular expression

    // finds phone number in format nnn-nnn-nnnn
    NSRange r;
    NSString *regEx = @"[0-9]{3}-[0-9]{3}-[0-9]{4}";
    r = [textView.text rangeOfString:regEx options:NSRegularExpressionSearch];
    if (r.location != NSNotFound) {
        NSLog(@"Phone number is %@", [textView.text substringWithRange:r]);
    } else {
        NSLog(@"Not found.");
    }

因为这些办法为与形式匹配的子字符串回来一个单一的规模值,因而ICU库的某些正则表达式功用要么不可用,要么有必要经过编程方式增加。此外,NSStringCompareOptions选项(如向后搜索、数字搜索和不区别重音符号的搜索)不可用,也不支撑捕获组。

在测试回来的规模时,您应该意识到根据字面字符串的搜索和根据正则表达式形式的搜索之间存在某些行为差异。一些形式能够成功匹配并回来一个长度为0的NSRange结构(在这种状况下,方位字段是有意义的)。其他形式能够成功匹配空字符串,或许在具有规模参数的办法中,匹配零长度的搜索规模。

这段感觉有点废话文学,就是注意下他供给的函数的回来值和参数

ICU正则表达式支撑

假如NSString对正则表达式的支撑不能满足您的需求,iOS在体系的BSD(非结构)等级包括了一个ICU 4.2.1库的修正版别。ICU(世界Unicode组件)是一个支撑Unicode和软件世界化的开源项目。安装的ICU版别包括支撑正则表达式所必需的头文件,以及一些与这些接口相关的修正,即:

parseerr.h
platform.h
putil.h
uconfig.h
udraft.h
uintrnal.h
uiter.h
umachine.h
uregex.h
urename.h
ustring.h
utf_old.h
utf.h
utf16.h
utf8.h
utypes.h
uversion.h
您能够在icu-project.org/apiref/icu4…4.2 API文档和用户攻略。

简略的文本输入

想要显现和处理文本的运用程序不只限于UIKit结构的文本和web方针。它能够完成自界说视图,这些视图能够从简略的文本输入到杂乱的文本处理和自界说输入。经过这些可用的编程接口,这些运用程序能够取得自界说文本布局、多阶段输入、自动校对、自界说键盘和拼写查看等功用。

您能够完成自界说视图,答应用户在刺进点输入文本,并在点击删去键时删去刺进点之前的字符。例如,即时消息运用程序能够有一个视图,答应用户输入他们的说话内容。

您能够经过子类化UIView或任何其他承继自UIResponder的视图类,并选用UIKeyInput协议,取得简略文本输入的才能。当您的视图类的实例成为第一响应者时,UIKit将显现体系键盘。UIKeyInput自身选用了UITextInputTraits协议,因而您能够设置键盘类型、回来键类型和键盘的其他特点。

注意:只要一部分言语和输入法在你仅仅选用UIKeyInput协议的时分就可用了。例如,任何多阶段输入法,如中文、日文、韩文和泰文是不行的。还需求选用了UITextInput协议。

要选用UIKeyInput,您有必要完成它声明的三个办法:hasText、insertText:和deleteBackward。要实践制作文本,您能够运用本章中总结的任何技能。但是,关于简略的文本输入,例如在自界说控件中的单行文本,UIStringDrawing和CATextLayer API是最合适的。

清单9-2说明晰自界说视图类的UIKeyInput完成。本例中的textStore特点是一个NSMutableString方针,用作文本的后台存储。该完成要么在字符串结尾追加字符,要么删去字符串中的最终一个字符(取决于按下的是字母数字键仍是删去键),然后重绘textStore。

Listing 9-2 Implementing simple text entry

- (BOOL)hasText {
    if (textStore.length > 0) {
        return YES;
    }
    return NO;
}
- (void)insertText:(NSString *)theText {
    [self.textStore appendString:theText];
    [self setNeedsDisplay];
}
- (void)deleteBackward {
    NSRange theRange = NSMakeRange(self.textStore.length-1, 1);
    [self.textStore deleteCharactersInRange:theRange];
    [self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
    CGRect rectForText = [self rectForTextWithInset:2.0]; // custom method
    [self.theColor set];
    UIRectFrame(rect);
    [self.textStore drawInRect:rectForText withFont:self.theFont];
}

为了在实践视图中制作文本,这段代码运用了NSString的UIStringDrawing类别中的drawInRect:withFont:办法。

与文本输入体系通讯

iOS的文本输入体系办理键盘。它将点击解释为特定键盘中特定键的按下,这些键盘适合某些言语。然后,它将相关字符发送到方针视图以刺进。如简略文本输入中所述,视图类有必要选用UIKeyInput协议来在刺进点刺进和删去字符。

但是,文本输入体系所做的不只仅是简略的文本输入。例如,它办理自动校对和多阶段输入,这些都是根据当时挑选和上下文的。多阶段文本输入关于表意文字言语(如汉字(日语)和汉字(汉语))是必需的,这些言语从音标键盘输入。要取得这些功用,自界说文本视图有必要经过选用UITextInput协议并完成相关的客户端类和协议来与文本输入体系通讯。

剩下的部分主张去看原文章,我感觉咋翻译都拗口。