NSTextView select specific line

时光毁灭记忆、已成空白 提交于 2019-12-11 15:38:56

问题


I am on Xcode 10, Objective-C, macOS NOT iOS.

Is it possible to programmatically select a line in NSTextView if the line number is given? Not by changing any of the attributes of the content, just select it as a user would do it by triple clicking.

I know how to get selected text by its range but this time i need to select text programmatically.

I've found selectLine:(id) but it seems to be for an insertion point. A pointer to the right direction would be great and very much appreciated.


回答1:


The Apple documentation here https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html should be useful for what you're attempting to do.

In their example of counting lines of wrapped text they use the NSLayoutManager method lineFragmentRectForGlyphAtIndex:effectiveRange https://developer.apple.com/documentation/appkit/nslayoutmanager/1403140-linefragmentrectforglyphatindex to find the effective range of the line, then increase the counting index to the end of that range (i.e. starting at the next line). With some minor modification, you can use it to find the range of the line you'd like to select, then use NSTextView's setSelectedRange: to select it.

Here's it modified to where I believe it would probably work for what you're attempting to accomplish:

- (void)selectLineNumber:(NSUInteger)lineNumberToSelect {
    NSLayoutManager *layoutManager = [self.testTextView layoutManager];
    NSUInteger numberOfLines = 0;
    NSUInteger numberOfGlyphs = [layoutManager numberOfGlyphs];
    NSRange lineRange;
    for (NSUInteger indexOfGlyph = 0; indexOfGlyph < numberOfGlyphs; numberOfLines++) {
        [layoutManager lineFragmentRectForGlyphAtIndex:indexOfGlyph effectiveRange:&lineRange];
        // check if we've found our line number
        if (numberOfLines == lineNumberToSelect) {
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [self.testTextView setSelectedRange:lineRange];
            }];
            break;
        }
        indexOfGlyph = NSMaxRange(lineRange);
    }
}

Then you could call it with something like:

[self selectLineNumber:3];

Keep in mind that we're starting at index 0. If you pass in a lineNumberToSelect that is greater than the numberOfLines, it should just be a no-op and the selection should remain where it is.



来源:https://stackoverflow.com/questions/54238610/nstextview-select-specific-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!