在NSTextView中查找光标的坐标



我有包装NSTextView实例垂直堆叠,例如:

The quick brown fox
jumps over the lazy dog
Jackdaws love my big
sphinx of quartz

我需要用上下箭头在它们之间移动。例如,当光标位于l之后时在"lazy"当用户按下向下箭头时,光标应该跳转到y之后。在"my"-就像这些句子在同一个文本视图中一样。

默认情况下,当光标位于最后一个换行行时按下向下箭头时,文本视图将其移动到该行的末尾。虽然我可以在NSTextViewDelegate中使用textView(_:doCommandBy:)来检测"箭头向下";选择器和覆盖默认行为,有两个问题:

  1. 我可以确定光标是否在最后一行,通过selectedRanges属性获得其位置,然后检查该位置后的换行字符,但不可能知道它是否在最后包装的行,即在当前文本视图的边界附近。

  2. 我需要知道光标的X坐标,以便将其放置在另一个文本视图中大致相同的X坐标上(字体不一定是固定宽度的,所以我不能依赖于字符数)。

我想这两个问题都可以通过NSLayoutManager解决,但是我无法理解它所有可用的方法。

这是相对容易的,这是我所做的(示例是用c#编写的)。首先,boundingRect(forGlyphRange:in:)获取光标在当前视图中的位置:

var cursorLocation = new NSRange(CurrentTextView.SelectedRange.Location, 0);
var cursorCoordinates = CurrentTextView.LayoutManager.BoundingRectForGlyphRange(cursorLocation, CurrentTextView.TextContainer).Location;

如果第二个文本视图在下面,则插入点将位于Y轴上的0处:

var insertionPoint = new CGPoint(cursorCoordinates.X, 0);

如果它在上面,那么应该使用另一个视图的高度(减少1,否则产生的字符索引将不正确,光标将被放置在行尾):

var insertionPoint = new CGPoint(cursorCoordinates.X, AnotherTextView.Bounds.Size.Height - 1);

获得插入点后,另一个视图需要成为第一响应者,然后characterIndexForInsertion(at:)完成这项工作:

Window.MakeFirstResponder(AnotherTextView);
var index = AnotherTextView.CharacterIndex(insertionPoint);
AnotherTextView.SelectedRange = new NSRange(index, 0);

最新更新