如何插入额外的字形?

时间:2014-02-19 19:32:50

标签: ios7 glyph nslayoutmanager

我想让UITextView在两种显示模式之间切换。 在模式1中,它应显示缩写,并在模式2中显示完整的单词。例如“Abbr。” vs“缩写”。

这样做的最佳方式是什么?请记住,某些单词可以使用相同的缩写,并且用户可以自由键入完整单词或缩写?

到目前为止,我试图将NSLayoutManager子类化。 假设我得到一个缩写字符串,我必须绘制完整的单词,我将实现以下方法:

-(void)setGlyphs:(const CGGlyph *)glyphs
  properties:(const NSGlyphProperty *)props
characterIndexes:(const NSUInteger *)charIndexes
        font:(UIFont *)aFont
 forGlyphRange:(NSRange)glyphRange
{
    NSUInteger length = glyphRange.length;
    NSString *sourceString = @"a very long string as a source of characters for substitution"; //temp.

unichar *characters = malloc(sizeof(unichar) * length+4);
CGGlyph *subGlyphs = malloc(sizeof(CGGlyph) * length+4);
[sourceString getCharacters:characters
                      range:NSMakeRange(0, length+4)];

CTFontGetGlyphsForCharacters((__bridge CTFontRef)(aFont),
                             characters,
                             subGlyphs,
                             length+4);

[super setGlyphs:subGlyphs
      properties:props
characterIndexes:charIndexes
            font:aFont
   forGlyphRange:NSMakeRange(glyphRange.location, length+4)];   

}

然而,当我尝试插入4个额外的字形时,此方法会抱怨无效的字形索引“_NSGlyphTreeInsertGlyphs invalid char index”。

1 个答案:

答案 0 :(得分:1)

你正在向错误的树上狂奔;在这种情况下尝试子类化NSLayoutManager是过度的。你的问题只是交换文本延伸(用缩写替换原文或原文缩写),所以只需这样做 - 在文本中,显示底层的NSMutableAttributedString。

你在评论中说#34;有些单词映射到相同的缩写"。没问题。假设您知道原始单词(如果您不知道该问题将无法解决),请将该原始单词存储为NSMutableAttributedString的一部分,即作为单词所在位置的属性。因此,当您替换缩写时,该属性保留,因此原始单词将保留,当您需要将其切换回来时为您准备好。

例如,给定此字符串:@"I love New York"您可以隐藏单词"纽约"作为"纽约":

占据的同一段文本中的属性
[attributedString addAttribute:@"realword" value:@"New York" range:NSMakeRange(7,8)];

现在您可以将该范围的文本设置为@"NY",但该属性仍然存在,您可以在将文本切换回未缩写的表单时查阅。

(我已经详细说明了这个答案,因为很多人都不知道你可以定义自己的NSAttributedString属性。这是一件非常有用的事情。)