5

私は今、この問題を 1 週間解決しようとしています。頭に浮かんだ多くのアイデアをテストしましたが、NSStringカスタム フォントのサイズを正しく計算できません。

UITextViewテキストを含むものと、UIViewの行の行番号を描画するものがありUITextViewます。問題は、NSString UIKit追加機能が のサイズの計算でタブ幅を無視していることNSStringです。

ここの図では、7 行目ではっきりとわかります。これは、 でレンダリングされた場合に改行された行でUITextViewあり、その後、すべての行が影響を受けます。

シミュレーターのスクリーンショット

使用しているフォントはAdob​​e Source Code Proです。

NSString UIKitAdditionsのすべての方法を試しましたが、成功しませんでした。

sizeWithFont

sizeWithFont:forWidth:lineBreakMode:

sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:

また、文字列内のすべてのタブを 4 つのスペースに置き換えようとしましたが、これは役に立ちますが、それでも常に機能するとは限りません。一部の行では役立ちますが、そうでない行もあります。

NSString高さを正しく計算する方法はありますか?CoreText多分?

1 つの小さなメモ。プロトコルのジオメトリヒットテストメソッドを使用してこれを解決しようとしましたUITextInputが、それらが機能している間、シミュレーターでの CPU 負荷は 100% であるため、実際のデバイスでは、特に約 1500 以上のファイルをロードすると、アプリが強制終了されます。コード行。

そして、これがLineNumbersView.mに使用しているコードの要点です。

4

1 に答える 1

1

Core Text と Core Text が常に正確に一致すると仮定するUITextViewと、後者は間違いなく解決策ですが、この問題については非常に簡単ではありません。

あなたは:

  1. 範囲全体に適切なフォントを設定して、メイン ビューにテキストの属性付き文字列を作成します。
  2. 属性付き文字列に適したフレームセッターを作成します ( を使用CTFramesetterCreateWithAttributedString)。
  3. CGPath文字列が描画される描画領域を記述する を作成します( として作成してからCGPathプロパティUIBezierPathを取得するか、作成して を使用します)。CGPathAddRect
  4. したがって、フレームセッター、パス、および関心のある文字列の部分範囲からフレームを作成します。これはおそらくすべてです (「 」を参照CTFramesetterCreateFrame)。
  5. CFArrayフレームから、出力する個々の行の を ( を使用して)取得できますがCTFrameGetLines、これらはソース行ではなく画面上のタイプセット行です。
  6. 行ごとに、含まれる元の文字列の範囲を取得できます (を使用CTLineGetStringRange)。これにより、ワード ラップではなく、元の改行文字の直後に開始する文字列を特定できます。
  7. の C 配列を取得することもできますCGPoint。ここで、それぞれが画面上の行の起点を表します ( CTFrameGetLineOrigins)。(6) で学んだことを使用して位置を調べ、関連する行の画面上の原点を取得できます。

さらに面白いことに、Core Text のピクセル出力は OS X と iOS で同じです。ただし、OS X は、方眼紙のように、画面のオリジナルを左下隅と見なします。iOS では、英語の読み順のように、左上隅にあると見なされます。大まかに言えば、正味の効果は、iOS Core Text で逆さまに描画されることです。したがって、それを考慮する必要があります。iOS の用語では、最初の行がフレームの一番下にあり、2 番目の行がその 1 行上にあるなどのように表示されます。これらの座標を反転する必要があります。

非常に多くのフープを飛び越えても、最終的にはわずか 100 行程度のコードになるでしょう。

于 2012-11-25T21:42:02.170 に答える