我知道为了显示一个popover我需要一个NSView,但我不认为有一个与插入符号相关联(在NSTextView内)。有没有办法在插入符号下方显示NSPopover?
我尝试分配一个NSView并使用(NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container
定位它,但弹出窗口不会出现(并且有一个原因,该方法返回NSRect: {{0, 0}, {0, 0}}
)。
答案 0 :(得分:10)
我不确定你是否还在寻找答案。我最近正在开发一个项目,它恰好需要一个与你描述的非常类似的功能。
您可以在NSTextView的子类中执行以下操作:
您要调用的函数是:showRelativeToRect:ofView:preferredEdge:
rect将是NSTextView内的一个rect,使用NSTextView坐标系,ofView是NSTextView,而preferredEdge是你希望这个popover事物挂钩的边缘。
现在,你说你想让PopOver的东西显示在插入符号下,你必须给他一个Rect,一个点是不够的。 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),这使得这种方法毫无用处。