问题标签 [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.
ios - NSLayoutManager 的基线对齐问题
我正在开发一个UIView
使用多个单独NSLayoutManager
对象呈现文本的自定义。(此视图的文本定位要求超出了内置文本视图类可以支持的范围。)当布局的文本是希伯来语时,我很难为其中一种布局获得正确的垂直位置。对于这篇文章的篇幅,我深表歉意,但我想包含尽可能多的相关细节。
问题
这是我要完成的示例:
“2”的基线与希伯来字母“ו”(以自定义字体呈现)的基线很好地对齐。但是,如果我将“2”的文本切换为希伯来数字(实际上是希伯来字母“ב”,在数字上下文中的值为 2),结果如下(“ב”太高):
这里唯一的变化是文本字符串。而不是"2"
,它是"\u{05b1}"
。我希望一切都在一个共同的基线上,并希望有任何解决问题的建议(这适用于所有希伯来数字,而不仅仅是"\u{05b1}"
)。
编码
(我应该提到,出于技术原因,我不能NSLayoutManager
对数字和正文都使用一个。)我试图通过垂直移动数字的渲染位置通过字体上升的差异来对齐基线。这是计算班次的代码:
这是我NSLayoutManager
为数字创建的方式:
后来,我使用以下方法渲染文本:
正文使用相同的逻辑处理,但没有offset
(当然还有不同的字体)。这对于阿拉伯数字(例如,“2”)非常有效,但对于希伯来数字(例如,“ב”)则无效。
更多信息
对于上面的图像,字体大小 ( .pointSize
) 和 ascent ( .ascender
) 属性是:
尺寸:文本 = 14.3890409469604;数字 = 8.63342465753425
上升:文本 = 16.159567469731;数字 = 8.2203017979452
我还生成了一些关于布局的诊断信息,但这些数字对我来说没有多大意义。这是打印信息的代码:
以下是两个文本(“2”和“\u{05d1}”)的结果:
label: 2
text size: (5.3958904109589, 10.3027782534247)
bounds: (0.0, 0.0, 5.3958904109589, 10.3027782534247)
label: ב
text size: (4.67931616438356, 9.19459726027397)
bounds: (-1.88208657534247, -0.578439452054793, 9.5054005479452, 9.77303671232876)
关于这个让我感到困惑的几件事:
- 希伯来文文本的边界从 x 和 y 的负值开始。负的 x 起源可能与希伯来语是从右到左的脚本有关,但是负的 y 起源呢?
- 报告的布局大小是边界高度和边界的 y 起点或(也许更准确地说)容器中文本的底部的代数和,而不是实际的整体大小。
NSAttributedString.size()
坏了吗? - 这些数字似乎都无法解释“2”和“\u{05d1}”在垂直位置上的视觉差异。
ios - 使用属性文本在自定义 UILabel 中定位字符坐标
我需要在我的 UILabel 中找到我的角色位置(它有 ParagraphLineSpacing 和多行的 AttributedText),
我有我的角色索引,但现在我无法从我的索引中获取 X 和 Y 坐标。
我翻译成我的 Swift 3.1 代码
但是,不幸的是,我不能真正使用这段代码,因为实际 GlyphRange 询问 NSRangePointer,而不是 NSRange,所以我将翻译后的代码更改为
我不明白什么
用法,所以我删除了它,现在代码可以工作了,但结果有 60% 不准确,尤其是当我的角色位于第二行或第三行时。我把这里的翻译搞砸了吗?或者有没有更好的方法来准确地获取我的角色坐标?
我用
让我的参数找到一个特定的字符
=======更新=======
我曾尝试自定义 UITextView 来访问其布局管理器,但不幸的是,如果有 2 行或更多行,位置仍然不准确。(仅当我的 textView 中只有 1 行时才准确)
我在这个新代码中遗漏了什么吗?快完成了
macos - 10.11 及更高版本中对 NSLayoutManager 的奇怪更改
我的目标是使文本选择行为类似于 Apple Pages、MS Word 和任何其他文本处理器,当 NSTextView 仅选择文本字形而不选择任何缩进或整个 NSTextContainer 大小时,就像默认 NSTextView 的行为一样。
考虑到这个目标,我将 NSLayoutManager 子类化并覆盖func rectArray(forCharacterRange charRange: NSRange, withinSelectedCharacterRange selCharRange: NSRange, in container: NSTextContainer, rectCount: UnsafeMutablePointer<Int>) -> NSRectArray?
在我的覆盖中,我只是计算了只绑定字形并拒绝任何缩进、空格等的新矩形。
一切正常。但突然在 macOS 10.11 中,Apple 确实弃用了我正在使用的方法。并建议func enumerateEnclosingRectsForGlyphRange: withinSelectedGlyphRange: inTextContainer: usingBlock:
改用。
但似乎这种新方法不像以前不推荐使用的方法那样起作用。不可能再自定义封闭的矩形了。我所能做的就是通过 rects TextKit 的计算来枚举。现在不可能实现理想的文本选择行为,因为矩形是只读的。顺便说一下,TextKit 根本不会调用新方法。所以我没有必要去想它。
我应该怎么办?
ios - NSAttributedString 的 enumerateAttribute 方法的块是否传递字符范围或字形范围?
tl; dr:如果我调用NSAttributedString
'senumerateAttribute:inRange:options:usingBlock:
方法,range
块的参数是否传递字形范围或字符范围?
我的应用程序中有一个文本视图,它的行为需要像 Notes.app 那样,当它不处于编辑模式时,它应该显示超链接(并且它们应该是可点击的),并且它应该在点击时进入编辑模式。UITextView
可编辑时不显示超链接,但如果它不可编辑,则它不会自行获得对点击的关注。在 iOS 11 之前,这可以通过使用UITapGestureRecognizer
文本视图上的 a 来触发编辑来解决,但似乎有些东西(可能是拖放?)改变了手势识别器的工作方式UITextView
(rdar://33009324)。
我的新的和改进的解决方案是一个自定义UIGestureRecognizer
,如果它看到一个不在超链接上的点击,并让文本视图上的所有其他识别器要求它在触发前失败。这是通过处理触摸、获取它们在文本视图中的位置、获取该点的字符索引、枚举NSLinkAttributeName
文本视图中的textStorage
以及检查我的字符索引是否与我返回的任何超链接重叠来实现的。如果是这样,那么用户点击了一个链接,这个识别器就会失败。
但是,如果点击的字符索引确实与链接相交,我需要确保点击实际上与链接的矩形相交,因为它可能是该链接是文本视图内容中的最后一件事,而触摸实际上是在文本的最后一行下方。我可以通过获取链接范围的矩形并检查它是否与我的接触点相交来做到这一点。我可以使用boundingRectForGlyphRange:inTextContainer:
它,但这会导致我的问题:链接的范围是字符范围还是字形范围?我需要先通过转换glyphRangeForCharacterRange:actualGlyphRange:
吗?
macos - 从 NSLayoutManager 接收即时布局更新
我目前正在布局管理器上设置一个委托并对 做出反应layoutManager(_:didCompleteLayoutFor:atEnd:)
,但是在视觉上更新布局(通过编辑文本或调整 NSTextView 的大小)和接收委托回调之间似乎有一点延迟。
这种延迟导致我的 UI 看起来不同步。您可以在下面看到一个示例,其中我添加和删除了两次句点,然后调整了两次窗口大小。在这两种情况下,您都可以看到 UI 的左侧有延迟反应。这是因为延迟layoutManager(_:didCompleteLayoutFor:atEnd:)
。
现在显然至少必须尽快提供一些布局信息,因为 NSTextView 正在立即更新。有没有办法更直接地回调 NSLayoutManager 的布局更新?
macos - 有没有办法用 NSLayoutManager 过滤掉某些范围?
我们有一个NSTextView
可能包含大量文本的内容。我正在使用它来替换NSTableView
,它在生成数千行时太慢了。我们还有一个NSSearchField
,它用于将其谓词应用于表的数组控制器,以将其缩小到仅包含给定字符串的行。现在我想对文本视图做同样的事情。
我尝试将自定义属性应用到 中找到的范围NSTextStorage
,然后使用该NSLayoutManagerDelegate
方法-layoutManager:shouldGenerateGlyphs:properties:characterIndexes:font:forGlyphRange:
将未标记范围的字形属性设置为NSGlyphPropertyNull
. 这导致了许多错误:
它使该应用程序陷入困境。有没有更好的方法来过滤 textStorage 的显示并只绘制我们找到的段落?
目前,它必须在 10.10 上运行。呜呜。
ios - 从 Storyboard 创建 UITextView 实例时如何注册 CustomLayoutManager
我要CustomeLayoutManager
适应UITextView
。所以我做了一个子类(CustomTextView
)UITextView
。
CustomTextView
由代码生成的工作正常。但是,我不知道CustomLayoutManager
在创建实例时如何适应stroyboard
谢谢。
swift - TextKit - 带有背景和间距的 UILabel
我一直在做这样的事情。
一切正常,直到我发现导致问题的字符串输入
输入字符串是“这是一个长标题sss \n Withssssssss”
基本上,“长”字似乎适合这个空间,但由于某种原因,它被绘制在下一行。
当我设置一个新的属性文本时,我总是以这种方式更新 textStorage
我的 UILabel 的子类调用
layoutManager.enumerateLineFragments(forGlyphRange: range) { (_, usedRect, _, glyphRange, _) in
里面drawText(in rect:)
这里 glyphRange 返回location 0 and length 15
第一个 LineFragments (直到 long ),矩形大小就是你在图片中看到的,因为它是我用来创建贝塞尔路径的那个。
这些是 TextKit 的所有对象的设置
我什么都试过了。一些委托方法,将逻辑四处移动。我不明白为什么在下一行中绘制该字符串。
ios - 当默认设置为 UITextAlignmentNatural 时,如何判断 UITextView 上的文本对齐方式
我有一个UITextView
具有属性UITextAlignmentNatural
但我想知道文本是从左到右还是从右到左对齐。如何判断是 LTR 还是 RTL
有关更多上下文,我正在尝试在我的NSLayoutManager
子类中执行此操作,因为我想使用特殊格式/大纲突出显示从左到右和从右到左的情况。
swift - 这是 UITextView 透明度错误吗?
这个问题与我昨天遇到的一个问题有关,我应该能够为此创建一个解决方法。当我进一步调查时,我发现它发生的范围比我最初想象的要广泛。我以前只在包含至少一个换行符的显示文本中注意到它,但下面的情况并非如此。
该问题似乎是由于使用 NSLayoutManager 的 boundingRect 方法来获取(除其他外)单个字符宽度,然后使用这些宽度来设置字符的 UITextView 框架宽度属性。这样做显然会导致文本视图的 backgroundColor 设置为 UIColor.clear 被忽略(即背景变得不透明)。下面的 Playground 代码重现了该问题,以红色文本显示,并显示了使用常量作为宽度的解决方法,在显示,并以黑色。字距越紧,效果越明显。