问题标签 [nslayoutmanager]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
547 浏览

swift - NSTextStorage 轻松/背景属性更改

我正在用一个相对较小的文本编辑器完成一个不错的应用程序。在执行语法高亮显示期间,我发现自己需要更改已识别标记的前景色属性。我注意到NSTextStorage有一个属性:

关于它的文档是:

一个布尔值,指示文本存储对象是否懒惰地修复属性。(只读)

讨论

子类化时,此属性的默认值为 NO,这意味着您的子类会在属性更改时立即修复它们。系统的具体子类覆盖此属性并将其设置为 YES。

我真的不知道如何解释这个......但这就是我所做的:

  1. 我正在更改内部识别标记的属性textStorage(textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int)(这是 NSTextStorage 的委托方法)。在这里,我正在检查此属性的值 - 它是 FALSE。
  2. 我完全按照 Apple 的建议( https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/Subclassing.html )对NSTextStorage 进行了子类化并覆盖了该属性。文本视图开始表现得很奇怪。实际上,对于小文本,它的性能还可以,但是一旦我打开一个 4 MB 的文件-它就会挂起并且……好吧……坏事开始发生在我的 mac 上。实际上,这种行为不依赖于fixesAttributesLazily属性的值。也许我的 NSTextStorage 实现很糟糕,或者至少不复杂。

任何在后台或懒惰地应用属性的技巧或......这样的东西都是受欢迎的。

另外:我知道有很多方法可以优化突出显示的语法。它可能会部分突出显示,使用某种逻辑,基于更改的范围......等等。我正在寻找的是一种在后台处理属性更改的方法。例如,目前当我将 4 MB 文件粘贴到文本视图时,它首先突出显示它(需要 2-3 秒),然后将其可视化。我正在寻找的效果是立即出现的文本,并在一段时间后出现 - 颜色。

我正在做的项目是用 Swift 编写的。

提前感谢大家的帮助。您可以通过 gmail dot com 的 ivailon 与我联系以获取详细信息,因为我不想在这里公开该应用程序……至少现在还没有 ;-)

0 投票
1 回答
1081 浏览

ios - NSLayoutManager、boundingRectForGlyphRange 和表情符号

我正在使用NSAttributedString'drawInRect(rect: CGRect)方法显示可能包含表情符号的文本。因为我想检测文本上的点击,所以我使用以下方法来查看哪个字符被点击:

这给出了我可以使用的正确索引,直到我开始向文本添加表情符号。一旦添加了表情符号,检测就会开始出现偏移。这使我查看了我正在寻找的字形的边界矩形。我注意到表情符号的边界矩形太大了。我设置了以下测试用例来检查差异:

执行此代码会产生以下结果CGRect

这意味着这两种方法给出了两种完全不同的尺寸!这不会是一个问题,但是“偏移”会堆叠更多行。

堆叠偏移示例

我为给我的角色设置了紫色背景characterIndexForPoint,给出boundingRectForGlyphRange了绿色轮廓的矩形,黄点是实际的敲击位置。请注意,绿色矩形与不同的字符很好地对齐,但是,这并没有任何指示,因为它恰好在这种特定情况下很好地对齐。

我是否忽略了一些明显的东西,或者这是 iOS 中的一个问题?

0 投票
0 回答
187 浏览

ios - 从 UITextView 检索准确的布局信息

我正在尝试将 UIButton 放置在 UITextView 中一大块动态生成的文本中的特定点。然而,事实证明,及时获得准确的坐标非常困难。已使用预生成的 NSAttributedString 设置了属性文本,现在,我将按钮添加到 NSLayoutManager 的委托方法中,因为这似乎是最合乎逻辑的地方。但是,我对其他选择持开放态度!

以下是相关代码:

这段代码很好用,但只有当你一直滚动到 UITextView 的底部时才会触发它。有没有办法确保对整个文本执行了所有布局,而不必一直滚动到视图底部?我在 NSLayoutManager 中尝试了许多方法,这些方法说它们“如果需要,执行字形生成和布局”,例如 glyphRangeForTextContainer()、ensureLayoutForCharacterRange() 等,但它们似乎没有满足我的需要。

我还尝试在代码中的其他位置添加按钮,例如在 viewWillAppear() 和 viewDidLoad() 中。但是,当我在这里尝试时,即使我调用了强制布局方法,当我调用 boundingRectForGlyphRange() 时,它也会返回 NSTextAttachment 图像的坐标,该坐标与图像在 textView 中实际结束的位置不准确,因此按钮最终出现在一个非常不准确的位置。

我毫不怀疑我错过了文本布局如何发生的重要内容,但我不知道它是什么。任何帮助将不胜感激!

0 投票
1 回答
374 浏览

macos - NSLayoutManager/NSTextContainer 忽略比例因子

我正在尝试NSAttributedString使用以下方法在给定宽度的情况下测量 的高度:

基本上,宽度是表格视图的大小减去滚动条和用于显示其他信息的每个单元格的一点点。只要文本比例 (via convertSliderValueToFontScale:) 为 1.0,此方法就非常有效。但是,如果我更改比例因子,则结果usedRectForTextContainer不正确 - 好像没有考虑比例因子。

比例setScaleFactor:forTextView:在 NSTextView 上设置如下(标量是实际的比例量):

有想法该怎么解决这个吗?

编辑:我有一个示例项目可以在这里尝试:Github。奇怪的是,如果比例 < 0,事情就会起作用,而且它们有时似乎随机地在 4.XXX 范围内工作......

0 投票
1 回答
640 浏览

swift - Swift 中的 drawGlyphsForGlyphRange(显示不可见字符)。replaceGlyphAtIndex 已弃用

我正在尝试使用以下类和 func 显示不可见字符,并且工作正常。

但是在 OS X 10.11 中不推荐使用 replaceGlyphAtIndex,我们需要使用 setGlyhs()

但是我在如何将 replaceGlyphAtIndex 转换为 setGlyphs 时遇到了困难。谁能建议我如何将下面的 replaceGlyphAtIndex 转换为 setGlyphs()?

我尝试如下,但它崩溃了。

谁能告诉我上面的代码行出了什么问题?

}

0 投票
1 回答
524 浏览

objective-c - 如何选择您可以在 NSTextView 中看到的所有文本?

我想要一种以编程方式仅选择边界中的文本并在窗口滚动或更改边界时进行更改的方法。

SelectAll不管用。我不想要整个文件。我的目标是对滚动到窗口中的任何文本做出反应,扫描它以查找关键词并在第二个窗口中显示上下文信息。

0 投票
2 回答
1521 浏览

swift - NSLayoutManager 无论我做什么都会隐藏换行符

我试图在我的 NSTextView 子类中显示不可见的字符,例如换行符。像覆盖 NSLayoutManager 的 drawGlyph 方法这样的常用方法是一个坏主意,因为它太慢并且不能在多页布局中正常工作。

我想要做的是覆盖 NSLayoutManager 的 setGlyph 方法,这样它将用“¶”字形替换不可见的“\n”字形,用“∙”替换“”。

它适用于“”空间字形,但对换行符没有影响。

然后我想出了一个主意:看起来 NSTypesetter 将新行字符范围标记为根本不应该处理的字符范围。所以我继承了 NSTypesetter 并覆盖了一个方法:

但它不起作用。NSLayoutManager 仍然不会为换行符生成一个字形,无论我创建什么字形。

我究竟做错了什么?

0 投票
1 回答
1187 浏览

objective-c - 强制 NSLayoutManager 用不同的字体绘制字形

我试图强制 NSLayoutManager 在某个范围内绘制具有不同属性的字形,但它仍然使用在 NSTextStorage 对象中设置的属性。

我试图从不同的字体创建 NSGlyph 并将其替换为 NSTypesetter 字形存储中的字体。但它是无用的 - 布局管理器仍然使用文本存储属性字符串中指定的字体和颜色绘制该字形。

如何强制布局管理器在某个范围内忽略这些属性并使用我需要的字体和颜色绘制我创建的字形?我需要这个,因为我正在研究绘制隐形字符的最有效方法。

0 投票
0 回答
441 浏览

ios - 使用 NSLayoutManager 计算字形运行边界

我正在尝试通过UITextView文本具有独特的背景颜色来实现视觉效果,例如:

示例文本效果

我尝试构建的方法是基于 Apple 用于计算线条的代码片段,然后按照本示例所示构建来计算线条的帧,例如:

然后我拿起框架并绘制矩形。我尝试过的这种方法和类似方法有一个共同的问题,即我计算的行的框架包含尾随空格,我不确定如何修剪它们(以及保持正确的文本流)。

我担心我可能想多了。有没有更简单的方法?

0 投票
0 回答
331 浏览

macos - 有什么方法可以获取 NSLayoutManager 中线条的精确指标(线条上升、线条下降等)?

这是对此的跟进。

在遇到某些字符组合在 Cocoa 和 Core Text 之间工作不一样的问题后,我决定给 Cocoa 的文本 API 一个机会。现在,我需要能够将一条线垂直分解为其每个组成部分:

  • 由于 NSParagraphStyle.paragraphSpacingBefore 导致的空白
  • 由于 NSParagraphStyle.lineHeightMultiple 导致的空白
  • 排版线上升
  • 印刷线下降
  • 排版行前导(行间距)
  • 由于 NSParagraphStyle.lineSpacing 的空白,但不是由于前导
  • 由于 NSParagraphStyle.paragraphSpacing 的空白

在 Core Text 中,对于上升、下降和前导行,我可以调用CTLineGetBoundsWithOptions(0)and CTLineGetBoundsWithOptions(kCTLineBoundsExcludeTypographicLeading)(这两个矩形的原点是基线,所以我知道在哪里切),然后为 CTParagraphStyle 条目重新创建 Core Text 的内部计算。

但我不确定如何处理 NSLayoutManager,并且尝试重新创建内部计算并没有太大帮助。

据我所知,Cocoa 的文本系统提供了以下获取公制矩形的方法:

  • -[NSLayoutManager lineFragmentRectForGlyphAtIndex:effectiveRange:]
  • -[NSLayoutManager lineFragmentUsedRectForGlyphAtIndex:effectiveRange:]
  • -[NSLayoutManager boundingRectForGlyphRange:inTextContainer:]

但是,这些不足以为我提供所需的数据。对于前两个,Apple 有这样的说法

除了线片段矩形本身之外,排版器还返回一个称为已使用矩形的矩形。这是实际包含要绘制的字形或其他标记的线片段矩形部分。按照惯例,两个矩形都包括行片段填充和根据字体的行高度量和段落的行间距参数计算的行间距。但是,段落间距(前后)和文本周围添加的任何空间,例如由中心间距文本引起的空间,仅包含在行片段矩形中,而不包含在使用的矩形中。

最后一个似乎与前两个完全无关:S

我确实尝试重新创建 Core Text 的逻辑来确定行上升和下降应该是什么,假设线路上升从行上所有字形的最大字体上升开始,但这并不完全奏效:而不是让先前的下降和当前的上升在字体上是同一行,没有像 Palatino 那样的前导,也没有段落样式,两条线相隔一些点:S

那么我想要的可能吗?如果没有,我将不得不研究如何让 Core Text 以与 Cocoa 相同的方式呈现和定位组合重音,或者更糟糕的是,手动布置线条以至​​少避免重叠(更糟糕的是,因为我假设 Apple 知道他们在做什么。 ..)

这是针对Mac OS X的;我需要以 10.8 或更高版本为目标。谢谢!