objective-c - 阐明 NSLayoutManager 和 NSTextContainer 在垂直布局方面的行为?

标签 objective-c cocoa swift nsview nslayoutmanager

代码示例

我有一个 NSLayoutManager、NSTextContainer 和 NSTextStorage 作为自定义 NSView(不是 TextView)中的属性,在 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)

NSTextContainer 的垂直 containerSize 被特意设置为 1,以查看它是否具有隐藏正在呈现的文本的预期效果 - 它没有!它在 View 中呈现此文本时没有差异 - 这是问题的主题!

drawRect 中,我包含以下几行来绘制文本:

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

调查结果

  1. 最好在像 NSTextView 这样的翻转坐标系中使用您的自定义 View ,否则我觉得我会陷入痛苦的世界!不管怎样,NSLayoutManager 总是开始在一个翻转的坐标系统中绘制它的文本(就像 NSTextView)
  2. NSTextContainercontainerSize.width 属性具有以下效果:它在所有级别(包括第一级)的行级别上绑定(bind)(我知道这很明显,但坚持使用我……)
  3. NSTextContainercontainerSize.height 属性有一个曲线球:它不会在第一行绑定(bind)即使包含 View 没有垂直显示的空间,但将绑定(bind)到后续行

*我花了很长时间才得出关于 containerSize.height 的假设,因为我只画了一条线! *

问题

  1. 我对 NSTextContainer 的结论是否正确?
  2. 从垂直角度控制文本绘制的最佳方式是什么?我想将我的单行文本放在 View 的底部(而不是像默认情况下那样将其 float 在顶部)

最佳答案

NSTextContainer 有一个 containerSize 属性。布局管理器正在布置该容器内的文本。据推测,容器在您的 View 中逻辑上位于 (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)

关于objective-c - 阐明 NSLayoutManager 和 NSTextContainer 在垂直布局方面的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28994528/

相关文章:

ios - UICollectionView 在单元格之间添加间隙

ios - Swift 3 JSON NSFastEnumerationIterator 没有下标成员

ios - 如何向另一个节点的方向移动节点

ios - 如何以编程方式设置划分为多个部分的静态表中的单元格

objective-c - 链接 UIKit 和 AppKit

swift - NSTableView初始化宽度问题

swift - 如何快速调用Mac API “Adding a new event”?

objective-c - 自定义UIButton

objective-c - 如何在 Objective-C 中设置文本字段的委托(delegate)?

ios - AVCaptureVideoPreviewLayer 能够使用 Quicktime 在横向模式下进行录制