Документация Apple здесь https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html должна быть полезна для того, что вы пытаетесь сделать.
В своем примере подсчета строк обернутого текста они используют метод NSLayoutManager lineFragmentRectForGlyphAtIndex:effectiveRange
https://developer.apple.com/documentation/appkit/nslayoutmanager/1403140-linefragmentrectforglyphatindex, чтобы найти эффективный диапазон строки, а затем увеличивают индекс подсчета до конца этого диапазона (т.е. начиная с следующая строка). С некоторыми незначительными изменениями вы можете использовать его, чтобы найти диапазон линии, которую вы хотите выделить, а затем использовать NSTextView setSelectedRange:
, чтобы выбрать ее.
Вот это изменение, где я думаю, что это, вероятно, сработает для того, чего вы пытаетесь достичь:
- (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);
}
}
Тогда вы можете назвать это как-то так:
[self selectLineNumber:3];
Имейте в виду, что мы начинаем с индекса 0. Если вы передаете lineNumberToSelect, который больше, чем numberOfLines, он должен быть просто неактивным, и выбор должен оставаться там, где он есть.