繁体   English   中英

从 NSTextView 获取插入符号 position (x, y)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM