2011-08-04 81 views
3

我知道,爲了顯示彈出窗口,我需要一個NSView,但我不認爲有一個與插入符號(在NSTextView內)有關聯。有沒有辦法在插入符號下方顯示NSPopover?NSPopover NSTextView下面的插入符號

我試圖分配一個NSView並使用(NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container來定位它,但彈出窗口不會出現(並且有一個原因,該方法返回NSRect: {{0, 0}, {0, 0}})。

+0

NSTextView是的NSView –

+0

@AP,對不起,我不明白你的意思。 NSTextView顯然是一個NSView。但是,脫字符不是。 – Donovan

回答

10

我不確定您是否仍在尋找答案。我最近正在研究一個需要類似於你所描述的特性的項目。

你可以做NSTextView的子類中,如下:

你要調用的函數是:showRelativeToRect:ofView:preferredEdge:

的RECT將是NSTextView裏面一個矩形,使用NSTextView座標系統,ofView是NSTextView,並且preferredEdge是你想要這個彈出式事物鉤住的邊緣。

現在,你是說你想讓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),這使得這個方法沒用。

NSPopover shows underneath the selected text

+0

謝謝。這是我需要的。 – Donovan

+0

如果文字不大並且不需要滾動,它會很好用。那麼這種情況呢? – Akki

+0

@Akki,很抱歉在幾個月後回覆:)我認爲這些東西適用於所有情況,因爲您可以在設計師中設計和定義這些動作。我沒有嘗試過,因爲我純粹是爲了好玩:p –