0

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

最好的方法是什么?请记住,某些单词可以具有相同的缩写,并且用户可以自由输入完整的单词或缩写?

到目前为止,我试图继承 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 无效字符索引”。

4

1 回答 1

1

你在错误的树上吠叫;在这种情况下尝试将 NSLayoutManager 子类化是矫枉过正的。您的问题只是交换文本延伸之一(将 abbrev 替换为 original 或 original 替换为 abbrev),所以只需这样做 - 在text中,显示底层 NSMutableAttributedString 。

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

例如,给定以下字符串:@"I love New York"您可以将单词“New York”作为属性隐藏在“New York”占据的同一段文本中:

[attributedString addAttribute:@"realword" value:@"New York" range:NSMakeRange(7,8)];

现在您可以将该范围的文本设置为@"NY"但该属性仍然存在,并且您可以在需要将文本切换回未缩写形式时查阅它。

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

于 2014-02-20T16:15:30.557 回答