3

コードサンプル

NSLayoutManager, NSTextContainer & NSTextStorage次のように初期化されたカスタムNSView(TextView ではない)にas プロパティがありawakeFromNib()ます。

    textStorage = NSTextStorage(attributedString: self.attributedString)

    layoutManager = NSLayoutManager()
    textContainer = NSTextContainer(containerSize: NSMakeSize(self.frame.size.width, 1))

    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)
    layoutManager.glyphRangeForTextContainer(textContainer)

containerSizeレンダリングされるテキストを非表示にする効果があるかどうかを確認するために、の垂直方向NSTextContainerは意図的に 1 に設定されていますが、そうではありません! ビューでのこのテキストのレンダリングに違いはありません-これが質問の主題です!

drawRectテキストを描画するために以下の行を含めます。

let glyphRange = layoutManager.glyphRangeForTextContainer(textContainer)
self.lockFocus()
layoutManager.drawGlyphsForGlyphRange(glyphRange, atPoint: NSMakePoint(0, 0))
self.unlockFocus()

所見

  1. 反転した座標系でカスタム ビューを操作するのが最善のようです。他の方法NSTextViewでは、苦痛の世界に陥りそうな気がします。これに関係なく、NSLayoutManager は常に反転した座標系で内部的にテキストの描画を開始します (のようにNSTextView) 。
  2. containerSize.widthプロパティにNSTextContainerは次の効果があります。最初のレベルを含むすべてのレベルの行レベルでバインドされます (明らかだとわかっていますが、私に固執してください...)
  3. containerSize.heightプロパティにNSTextContainerはカーブボールがあります。含まれているビューに垂直に表示する余地がない場合でも、最初の行ではバインドされませんが、後続の行ではバインドされます

containerSize.height*線を一本しか引いていなかったので、この仮説にたどり着くまでに長い時間がかかりました! *

質問

  1. に関する私の結論はNSTextContainer正しいですか?
  2. 垂直方向の視点からテキスト描画を制御する最良の方法は何ですか? テキストの 1 行をビューの下部に配置したいと考えています (デフォルトのように上部に浮かせません)。
4

1 に答える 1

2

NSTextContainerプロパティを持っていcontainerSizeます。レイアウト マネージャーは、そのコンテナー内にテキストをレイアウトしています。おそらく、コンテナーは論理的にビューの (0, 0) に配置されているものですが、テキストはその上から配置されています。そのため、コンテナにたるみがあります。

から返された四角形に基づいてコンテナーのサイズを変更し、-[NSLayoutManager usedRectForTextContainer:]収まるようにサイズを変更できます。


アップデート:

あなたのこのようなコードは、あなたdrawRect()が達成したいことのために働くべきだと思います:

layoutManager.ensureLayoutForTextContainer(textContainer)
var rect = layoutManager.usedRectForTextContainer(textContainer)
rect.origin.x += 2
rect.origin.y = NSMaxY(self.bounds) - NSHeight(rect) - 4

let glyphRange = layoutManager.glyphRangeForTextContainer(textContainer)
layoutManager.drawGlyphsForGlyphRange(glyphRange, atPoint:rect.origin)
于 2015-03-11T18:36:07.480 に答える