2011-08-04 2 views
3

Я знаю, что для отображения popover мне нужен NSView, но я не думаю, что есть один связанный с кареткой (внутри NSTextView). Есть ли способ показать NSPopover ниже каретки?NSPopover ниже каретки в NSTextView

Я попытался выделить NSView и поместить его с помощью (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container, но popover не появится (и есть причина, этот метод возвращает NSRect: {{0, 0}, {0, 0}}).

+0

NSTextView является NSView –

+0

@AP, мне очень жаль, что я не могу понять, что вы имеете в виду. NSTextView - это, очевидно, NSView. Но карет - нет. – Donovan

ответ

10

Я не уверен, что вы все еще ищете ответ. Недавно я работал над проектом, который нуждается в очень похожей функции, как вы описали.

Вы можете сделать следующее внутри подкласса NSTextView:

функция, которую вы собираетесь назвать это: showRelativeToRect: ofView: preferredEdge:

Прямоугольник будет прямоугольник внутри NSTextView, используя Система координат NSTextView, theView - это 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]; 

и это результат.

Все, что мне интересно, это то, что если есть способ конвертировать с использованием системных функций, хотя я попытался преобразоватьRect: toView, но поскольку этот метод написан в делегате, NSTextView всегда имеет систему координат (0,0), что делает этот метод бесполезным.

NSPopover shows underneath the selected text

+0

Спасибо. Это то, что мне нужно. – Donovan

+0

Он работает хорошо, если текст невелик и нет необходимости прокручивать. Как насчет этой ситуации? – Akki

+0

@Akki, извините за ответ через несколько месяцев :) Я думаю, что этот материал работает для всех случаев, так как вы могли бы проектировать и определять эти действия в дизайнере. Я не пробовал, так как я делаю это исключительно ради удовольствия: p –

 Смежные вопросы

  • Нет связанных вопросов^_^