在 SwiftUI 和 macOS 11 中获取多行 + 可滚动 TextView 中子字符串的 X/Y 位置
Get X/Y position of substring in multi-line + scrollable TextView in SwiftUI and macOS 11
计划
我已经使用以下实现在我的 Swift-app (macOS 11) 中实现了 TextView,这通过将 TextView 放入 ScrollViewer 使其可滚动:
https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0
现在,我正在尝试在文本的一侧显示注释,最终看起来应该是这样的:
我计划通过
实现这一目标
- 将自定义 AttributedString-key 设置为 TextView 的 NSAttributedString
- 在左侧添加第二个 ScrollView,其中包含注释,并同步两个 ScrollView 的滚动位置(即,左边一个和 TextView 中的那个。)
- 使用相关子字符串和place/draw annotation/connecting行计算每个注释的Y位置
问题
我尝试使用 textView.firstRect 函数(我在所有其他旧的 SO 问题中找到)来评估子字符串的 Y 位置,但是, 它似乎 return 正确的值,除非使用了 TextView 第一行中子字符串的位置。
class TextViewExtended: NSTextView {
func getAllRectangles() {
for CurRange in self.selectedRanges {
self.layoutManager!.ensureLayout(for: self.textContainer!) // S.
let CurRangeAsNSRange:NSRange = CurRange as! NSRange
var actualRange = NSRange(location: 0, length: self.attributedString().length)
let rect = self.firstRect(forCharacterRange: CurRangeAsNSRange, actualRange: &actualRange)
}}}
问题
在 SwiftUI 和 macOS 11 中确定 TextView 子字符串坐标的正确方法是什么?或者有没有人有更简单的想法,我可以如何实现这一目标?
非常感谢您的建议!
Ps。我省略了 TextView 实现的完整代码,因为它紧跟上面的教程;如果我应该添加其他代码,请告诉我。
尝试使用 actualRange
更新矩形。像这样的事情:
rect = textView.firstRect(forCharacterRange: range, actualRange: &actualRange)
while actualRange.upperBound < rangeToCheck.upperBound {
rangeToCheck.length = (rangeToCheck.upperBound - actualRange.upperBound)
rangeToCheck.location = actualRange.upperBound
rect = textView.firstRect(forCharacterRange: rangeToCheck, actualRange: &actualRange)
}
计划
我已经使用以下实现在我的 Swift-app (macOS 11) 中实现了 TextView,这通过将 TextView 放入 ScrollViewer 使其可滚动:
https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0
现在,我正在尝试在文本的一侧显示注释,最终看起来应该是这样的:
我计划通过
实现这一目标- 将自定义 AttributedString-key 设置为 TextView 的 NSAttributedString
- 在左侧添加第二个 ScrollView,其中包含注释,并同步两个 ScrollView 的滚动位置(即,左边一个和 TextView 中的那个。)
- 使用相关子字符串和place/draw annotation/connecting行计算每个注释的Y位置
问题
我尝试使用 textView.firstRect 函数(我在所有其他旧的 SO 问题中找到)来评估子字符串的 Y 位置,但是, 它似乎 return 正确的值,除非使用了 TextView 第一行中子字符串的位置。
class TextViewExtended: NSTextView {
func getAllRectangles() {
for CurRange in self.selectedRanges {
self.layoutManager!.ensureLayout(for: self.textContainer!) // S.
let CurRangeAsNSRange:NSRange = CurRange as! NSRange
var actualRange = NSRange(location: 0, length: self.attributedString().length)
let rect = self.firstRect(forCharacterRange: CurRangeAsNSRange, actualRange: &actualRange)
}}}
问题
在 SwiftUI 和 macOS 11 中确定 TextView 子字符串坐标的正确方法是什么?或者有没有人有更简单的想法,我可以如何实现这一目标?
非常感谢您的建议!
Ps。我省略了 TextView 实现的完整代码,因为它紧跟上面的教程;如果我应该添加其他代码,请告诉我。
尝试使用 actualRange
更新矩形。像这样的事情:
rect = textView.firstRect(forCharacterRange: range, actualRange: &actualRange)
while actualRange.upperBound < rangeToCheck.upperBound {
rangeToCheck.length = (rangeToCheck.upperBound - actualRange.upperBound)
rangeToCheck.location = actualRange.upperBound
rect = textView.firstRect(forCharacterRange: rangeToCheck, actualRange: &actualRange)
}