swiftui - 在 SwiftUI 和 macOS 11 中获取多行 + 可滚动 TextView 中子字符串的 X/Y 位置
问题描述
计划
我已经使用以下实现在我的 Swift 应用程序(macOS 11)中实现了一个 TextView,它通过将 TextView 放入 ScrollViewer 中来使其可滚动:
https://gist.github.com/unnamedd/6e8c3fbc806b8deb60fa65d6b9affab0
现在,我试图在文本的一侧显示注释,最终应该看起来像这样:
我计划通过
- 将自定义 AttributedString-key 设置为 TextView 的 NSAttributedString
- 在左侧添加第二个 ScrollView,其中包含注释,并同步两个 ScrollView 的滚动位置(即左侧和 TextView 中的)。
- 使用相关子字符串计算每个注释的 Y 位置并放置/绘制注释/连接线
问题
我尝试使用textView.firstRect函数(我在所有其他旧的 SO-questions 中找到)评估子字符串的 Y 位置,但是,除非子字符串在其中的位置,否则它似乎不会返回正确的值使用 TextView 的第一行。
class TextViewExtended: NSTextView {
func getAllRectangles() {
for CurRange in self.selectedRanges {
self.layoutManager!.ensureLayout(for: self.textContainer!) // S. https://stackoverflow.com/a/30752520/2624880
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 子字符串坐标的正确方法是什么?或者有没有人有更简单的想法我怎么能做到这一点?
非常感谢您的任何建议!
附言。我省略了 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)
}
推荐阅读
- git - Github 上的 SSH 访问
- javascript - 在插件中动态初始化多个输入字段
- reactjs - 对现有的 React.js 项目慢慢实现 redux
- wordpress - WooCommerce 不包括运费计算器的运输类别
- python - 如何组合多个 python 正则表达式参数?
- keras - 有没有办法在通话期间更改变量?
- bash - 如何将输出存储为变量
- intellij-idea - 有没有办法从 kotlin 项目的 build.gradle 获取版本?
- reactjs - 维护单个组件的多个状态
- javascript - jQuery Draggable - 在 html5 原生 Drag And Drop api 事件上创建可拖动并开始拖动