我有一个NSTextField,里面有一个句子.我想为句子中的每个单词找到一个rect(理想情况下)或位置,以便在那些位置(NSTextField之外)执行操作.
在NSTextView/UITextView中这样做似乎是可以实现的与NSLayoutManager.boundingRectForGlyphRange
,但没有NSLayoutManager是NSTextView(和UITextView的)都似乎更具挑战性的一点.
在NSTextField中找到给定单词的位置的最佳方法是什么?
它需要一个几乎没有记录的魔法和另一个完全没有记录的位.这是Objective-C代码.不要在Swift中使用它,对不起.
NSRect textBounds = [textField.cell titleRectForBounds:textField.bounds]; NSTextContainer* textContainer = [[NSTextContainer alloc] init]; NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init]; NSTextStorage* textStorage = [[NSTextStorage alloc] init]; [layoutManager addTextContainer:textContainer]; [textStorage addLayoutManager:layoutManager]; textContainer.lineFragmentPadding = 2; layoutManager.typesetterBehavior = NSTypesetterBehavior_10_2_WithCompatibility; textContainer.containerSize = textBounds.size; [textStorage beginEditing]; textStorage.attributedString = textField.attributedStringValue; [textStorage endEditing]; NSUInteger count; NSRectArray rects = [layoutManager rectArrayForCharacterRange:matchRange withinSelectedCharacterRange:matchRange inTextContainer:textContainer rectCount:&count]; for (NSUInteger i = 0; i < count; i++) { NSRect rect = NSOffsetRect(rects[i], textBounds.origin.x, textBounds.origin.y); rect = [textField convertRect:rect toView:self]; // do something with rect }
将typesetterBehavior
被记录在这里.这lineFragmentPadding
是根据经验确定的.
根据您计划对矩形进行的确切操作,您可能希望{ NSNotFound, 0 }
作为选定的字符范围传递.
为了提高效率,通常需要保留文本对象,而不是每次都实例化它们.您只需每次将文本容器containerSize
和文本存储attributedString
设置为适当的值.