NSPopView下面的插入符号 [英] NSPopover below caret in NSTextView
问题描述
我知道,为了显示一个popover我需要一个NSView,但我不认为有一个关联与插入符号(在NSTextView内)。有没有办法在脱机下面显示NSPopover?
I know that in order to show a popover I need an NSView, but I don't think that there is one associated with the caret (inside the NSTextView). Is there a way to show a NSPopover below the caret?
我试图分配NSView并使用(NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container
,但popover不会出现(并且有一个原因,该方法返回 NSRect:{{0,0},{0,0}}
)。
I tried to alloc a NSView and position it using (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container
, but the popover will not appear (and there's a reason, that method returns NSRect: {{0, 0}, {0, 0}}
).
推荐答案
我不知道你是否仍在寻找答案。
I'm not sure if you are still looking for answer. I recently was working on a project which happens to need a very similar feature like you described.
您可以在NSTextView的子类中执行以下操作:
You can do the following inside a subclass of NSTextView:
你要调用的函数是:showRelativeToRect:ofView:preferredEdge:
the function you are going to call is : showRelativeToRect:ofView:preferredEdge:
rect将是NSTextView内部的一个rect,使用NSTextView坐标系统,ofView是NSTextView,而preferredEdge是你想要的这个popover事物挂钩的边缘。
the rect will be a rect inside the NSTextView, using the NSTextView coordinate system, the ofView is the NSTextView, and the preferredEdge is the edge you want this popover thing to hook with.
现在,你说你想要PopOver的东西要显示在插入符号下,好了你得给他一个Rect,一个点是不够的。 NSTextView有一个称为selectedRange的选择器,它给你所选文本的范围,你可以使用它来定位你的插入符号。
now, you are saying that you want the PopOver thing to show under the caret, well you have to give him a Rect, a Point is not enough. The NSTextView has a selector called selectedRange, which gives you the range of the selected text, you can use that to locate your caret.
下一件事是调用firstRectForCharacterRange该类必须委托NSTextInputClient),此方法将返回NSTextView内所选文本的屏幕坐标,然后将它们转换为NSTextView坐标系,您将能够在正确的位置显示NSPopover事件。这是我的代码这样做。
the next thing is to call firstRectForCharacterRange (the class must delegate NSTextInputClient), this method will return a screen coordinate of the selected text inside the NSTextView, then you convert them into the NSTextView coordinate system, you will be able to show the NSPopover thing at a correct position. Here's my code of doing this.
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)
All the thing I am wondering is that if there is a way to convert using System functions, although I tried the convertRect:toView, but since this method is written in a delegate, the NSTextView always has the coordinate system of (0,0), which makes this method useless.
这篇关于NSPopView下面的插入符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!