23

明らかに「バグ」と思われるものについては、UITextView は他の UIKit 要素のようにカーニングをサポートしていないようです。カーニングを機能させるための回避策はありますか?

明確にするために、すべての文字間の一般的な間隔ではなく、フォント ファイルで定義されている文字のペア間の間隔について話しているのです。を とともに使用するNSAttributedStringと、NSKernAttributeNameすべての文字間の間隔が調整されますが、組み込みの文字ペアはまだ機能しません。

例えば:

ここに画像の説明を入力

これを修正する回避策はありますか?

私が見つけた簡単な回避策の 1 つは、カーニングを有効にする CSS スタイルを UITextView に追加することです。文書化されていない方法を使用するとsetContentToHTMLString:、css をテキスト ビュー内の秘密の Web ビューに挿入できます。

NSString *css = @"*{text-rendering: optimizeLegibility;}";
NSString *html = [NSString stringWithFormat:@"<html><head><style>%@</style></head><body>Your HTML Text</body></html>", css];
[textView performSelector:@selector(setContentToHTMLString:) withObject:html];

これにより、問題はすぐに修正されます。ただし、これによりアプリが拒否される可能性が非常に高いようです。css をテキストビューに忍び込ませる安全な方法はありますか?

私が実験した他の回避策には、次のものがあります。

webview と contenteditable プロパティを使用します。これは理想的ではありません。webview は、簡単に非表示にできない入力アクセサリ ビューなど、邪魔になる余分なものをたくさん処理するからです。

a をサブクラス化し、UITextViewコア テキストを使用してテキストを手動でレンダリングします。すべての選択項目も再構成する必要があるため、これは私が望んでいたよりも複雑です。UITextViewの とのプライベート サブクラスのため、完全に不可能ではないにしても、これはお尻の大きな痛みですUITextPositionUITextRange

4

6 に答える 6

37

を使用すると、アプリがおそらく拒否されることは間違いありません@selector(setContentToHTMLString:)。ただし、単純なトリックを使用してセレクターを動的に構築し、検証中に検出されないようにすることができます。

NSString *css = @"*{text-rendering: optimizeLegibility;}";
NSString *html = [NSString stringWithFormat:@"<html><head><style>%@</style></head><body>Your HTML Text</body></html>", css];
@try {
    SEL setContentToHTMLString = NSSelectorFromString([@[@"set", @"Content", @"To", @"HTML", @"String", @":"] componentsJoinedByString:@""]);
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [textView performSelector:setContentToHTMLString withObject:html];
    #pragma clang diagnostic pop
}
@catch (NSException *exception) {
    // html+css could not be applied to text view, so no kerning
}

setContentToHTMLString:呼び出しを @try/@catch ブロック内にラップすることで、iOS の将来のバージョンでメソッドが削除された場合でもアプリがクラッシュしないようにすることもできます。

プライベート API を使用することは一般的に推奨されませんが、この場合、CoreText で UITextView を書き換えるよりも、小さなハックを使用する方が完全に理にかなっていると思います。

于 2012-11-14T21:43:31.473 に答える
3

これを少し調べたところ、カーニングが欠落している理由は、UITextViewがデフォルトでカーニングがオフになっているUIWebDocumentViewを内部的に使用しているためであることがわかりました。

UITextViewの内部動作に関するいくつかの情報:http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

残念ながら、カーニングを有効にするための認可された方法はありません。カモフラージュされたセレクターを使用してハックを使用することは絶対にお勧めしません。

これが私のレーダーです。複製することをお勧めします:http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-font-kerning/

これで、setAttributedTextを介してUITextViewにテキストを設定する場合、開発者はKerningがデフォルトでオンになることを期待していると主張します。これは、CoreTextを介してテキストをレンダリングする出力と最もよく一致するためです。

于 2012-12-16T18:54:46.163 に答える
1

Try this:

[textView_ setValue:@"hello, <b>world</b>" forKey:@"contentToHTMLString"];

It works in my test. I haven't tried it in the app store of course.

于 2012-11-15T06:36:11.977 に答える
0

ここを見ましたか: https://github.com/AliSoftware/OHAttributedLabel ? このプロジェクトを見ると、 (このクラスによって提供される) マークアップを使用しているアプリがアプリ ストアにいくつかあるようです。おそらく、このクラスを使用するか、そこからいくつかの実装のアイデアを収集することができます。おそらく、あなたのアプリはそのままで合格するでしょう。

于 2012-11-09T15:48:06.910 に答える
0

iOS6 ではUITextView、新しい属性 がattributedTextあり、これに を割り当てることができますNSAttributedString。私はそれを試していませんが、属性ではなくテキストビューのこの属性を設定した場合に、目的のカーニングが得られるかどうかを確認するのは興味深いでしょうtext。また、パブリック インターフェイスであるという追加の利点もあります。

于 2012-11-14T21:51:30.420 に答える