在NSTextView中的插入符号下面的NSPopover

Don*_*van 3 cocoa nstextview popover nspopover

我知道为了显示一个popover我需要一个NSView,但我不认为有一个与插入符号相关联(在NSTextView内).有没有办法在插入符号下方显示NSPopover?

我试图分配一个NSView并使用它定位(NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container,但弹出窗口不会出现(并且有一个原因,该方法返回NSRect: {{0, 0}, {0, 0}}).

She*_*ong 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];
Run Code Online (Sandbox Code Playgroud)

这就是结果.

我想知道的是,如果有一种使用系统函数进行转换的方法,虽然我尝试了convertRect:toView,但由于此方法是在委托中编写的,因此NSTextView始终具有(0,0)的坐标系,这使得这种方法毫无用处.

NSPopover显示在所选文本下方