0

UITextView で 2 つの表示モードを切り替えたい。モード 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 をサブクラス化しようとするのはやり過ぎです。あなたの問題は、テキストストレッチを交換することの1つにすぎない(abbrevをオリジナルに、またはオリジナルをabbrevに置き換える)ので、それを行うだけです-テキストで、基になる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 に答える