[英]Get the caret position (x, y) from NSTextView
The NSTextView will send -textViewDidChangeSelection:
when the selection changes.
如何在此通知中获取插入符号行和 position?
蒂亚!!
编辑:
这是我的代码:
NSRange selectedRange = [self selectedRange];
NSRange newRange = [[self layoutManager] glyphRangeForCharacterRange:selectedRange actualCharacterRange:NULL];
NSRect rect = [[self layoutManager] boundingRectForGlyphRange:newRange inTextContainer:[self textContainer]];
NSInteger insertionPoint = [[[self selectedRanges] objectAtIndex:0] rangeValue].location;
这些是来自 lldb 的值(当我单击文本控件的第 3 行 position 3 时):
Target 0: (text) stopped.
(lldb) p selectedRange
(NSRange) $0 = location=65, length=0
(lldb) p newRange
(NSRange) $1 = location=65, length=0
(lldb) p rect
(NSRect) $2 = (origin = (x = 60.73876953125, y = 32), size = (width = 0, height = 16))
(lldb) p insertionPoint
(NSInteger) $3 = 65
(lldb)
现在,第 3 行实际上是一个大的第 1 行,插入了几个软“回车”符号。 这意味着我没有按 Enter - 行在最后换行。
哦,我期望得到的是 (3,3 - line 3, position 3) 而不是 (65 - position 相对于文本的开头)。
NSLayoutManager
的方法lineFragmentRectForGlyphAtIndex:effectiveRange:
返回字形所在的线片段的矩形,并且(可选地)通过引用返回该片段中的整个字形范围。 通过行上的字形范围,可以计算行上的字符索引。 可以通过对上一行的字形重复调用此方法来计算行索引。 当插入点位于文本末尾时,则没有字形,因此使用最后一个字形并调整行和字符索引。
NSUInteger lineNr = 0;
NSUInteger characterNr = 0;
BOOL extraCharacter = NO;
if (textView.textStorage.length > 0) {
NSUInteger characterIndex = [textView selectedRange].location; // character index in text
if (characterIndex >= textView.textStorage.length) {
// there is no glyph after the insertion point, use the last glyph and add a character later
characterIndex--;
extraCharacter = YES;
}
NSLayoutManager *layoutManager = textView.layoutManager;
NSUInteger glyphIndex = [layoutManager glyphIndexForCharacterAtIndex:characterIndex];
NSRange effectiveRange;
NSRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:&effectiveRange];
// effectiveRange is the glyph range of the line
NSUInteger lineStart = [layoutManager characterIndexForGlyphAtIndex:effectiveRange.location];
characterNr = characterIndex - lineStart;
if (extraCharacter) {
// extraLineFragmentRect is not equal to NSZeroRect if the last character in the text causes a line or paragraph break
if (NSEqualRects(layoutManager.extraLineFragmentRect, NSZeroRect)) {
characterNr++;
}
else {
characterNr = 0;
lineNr++;
}
}
// count lines until effectiveRange is at the start of the text
while (effectiveRange.location > 0 && effectiveRange.location != NSNotFound) {
lineNr++;
glyphIndex = effectiveRange.location - 1;
lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:&effectiveRange];
}
}
NSLog(@"Line: %li, character: %li", (long)lineNr, (long)characterNr);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.