我不确定您是否还在寻找答案。我最近正在开发一个项目,该项目恰好需要像您所描述的非常相似的功能。
您可以在 NSTextView 的子类中执行以下操作:
您要调用的函数是:showRelativeToRect:ofView:preferredEdge:
矩形将是 NSTextView 内的矩形,使用 NSTextView 坐标系,ofView 是 NSTextView,preferredEdge 是您希望此弹出窗口挂钩的边缘。
现在,你说你希望 PopOver 东西显示在插入符号下,那么你必须给他一个 Rect,一个 Point 是不够的。 NSTextView 有一个名为 selectedRange 的选择器,它为您提供所选文本的范围,您可以使用它来定位插入符号。
接下来是调用firstRectForCharacterRange(该类必须委托NSTextInputClient),该方法将返回NSTextView内所选文本的屏幕坐标,然后将它们转换为NSTextView坐标系,您将能够在以下位置显示NSPopover东西正确的立场。这是我执行此操作的代码。
NSRect rect = [self firstRectForCharacterRange:[self selectedRange]]; //screen coordinates
// Convert the NSAdvancedTextView bounds rect to screen coordinates
NSRect textViewBounds = [self convertRectToBase:[self bounds]];
textViewBounds.origin = [[self window] convertBaseToScreen:textViewBounds.origin];
rect.origin.x -= textViewBounds.origin.x;
rect.origin.y -= textViewBounds.origin.y;
rect.origin.y = textViewBounds.size.height - rect.origin.y - 10; //this 10 is tricky, if without, my control shows a little below the text, which makes it ugly.
NSLog(@"rect %@", NSStringFromRect(rect));
NSLog(@"bounds %@", NSStringFromRect([self bounds]));
if([popover isShown] == false)
[popover showRelativeToRect:rect
ofView:self preferredEdge:NSMaxYEdge];
这就是结果。
我想知道的是,是否有一种方法可以使用系统函数进行转换,虽然我尝试了convertRect:toView,但由于此方法是在委托中编写的,因此 NSTextView 始终具有 (0,0) 坐标系,这使得该方法毫无用处。