Пользовательский вид Mavericks и NSStatusItem с несколькими мониторами

Начиная с Mavericks каждый экран имеет свою собственную строку состояния. Это также означает, что приложение, работающее в строке состояния (с использованием NSStatusItem), теоретически имеет несколько связанных объектов NSStatusItem. На практике, хотя пользователь может видеть несколько «экземпляров» вашего NSStatusItem, это всего лишь один (я проверял это). Теперь возникает следующая проблема, когда вы работаете с пользовательским представлением в значке состояния: когда пользователь щелкает значок состояния, я программно «выделяю» его с помощью метода drawStatusBarBackgroundInRect. Проблема в том, что каждый «экземпляр» значка состояния (по одному на экран) выделен, хотя пользователь только что щелкнул один из них. Это поведение отличается от значка состояния без пользовательского представления. Есть ли способ реализовать это правильно?

В качестве хорошего примера просто щелкните значок состояния Dropbox, когда вы используете несколько дисплеев. Вы также заметите выбор значка на другом экране.


person Niels Mouthaan    schedule 16.11.2013    source источник


Ответы (3)


Ответ от Apple, упомянутый в ветке JLinX Apple Dev Forums:

Элементы состояния с несколькими строками меню

В версии 10.9 представлено несколько строк меню, каждая из которых отображает элементы состояния. Если ваш элемент состояния имеет настраиваемый вид, этот вид располагается в одной строке меню, а другие строки меню получают «клон», который выглядит идентично. Клоны не отображаются в API. Клоны рисуются путем перенаправления рисунка вашего пользовательского вида в другое окно. Это означает, что ваш элемент состояния не должен делать предположений о назначении чертежа. Например, не следует предполагать, что вызов drawRect: предназначен для окна представления или что разрешение места назначения рисования соответствует разрешению экрана элемента состояния. Вы также не должны предполагать, что элемент состояния находится на каком-либо конкретном дисплее, за исключением случаев, описанных ниже. Клоны перерисовываются только в NSDefaultRunLoopMode. Это позволяет элементу состояния ограничить подсветку одним дисплеем, управляя циклом выполнения в другом режиме, таком как NSEventTrackingRunLoopMode. Например, если вы хотите имитировать меню, вы должны реализовать mouseDown:, чтобы показать свое окно, и запустить цикл выполнения в NSEventTrackingRunLoopMode, пока не решите, что окно должно быть закрыто. Пока цикл выполнения находится в этом режиме, будет перерисовываться только элемент истинного состояния. Клонированные элементы состояния не будут перерисовываться, и поэтому они не будут отображать какую-либо подсветку, примененную к истинному элементу состояния. При щелчке элемента статуса клона клон меняет местоположение с элементом истинного статуса. Это означает, что местоположение и экран окна элемента состояния надежно определяются внутри mouseDown:. Вы можете получить доступ к этой информации из своего пользовательского представления, например, используя [экран [окна просмотра]] для размещения окна на том же экране, что и элемент состояния.

person Valentin Shergin    schedule 01.08.2015

Ваш вопрос обсуждается здесь. Попробуйте нарисовать свой собственный вид в цикле выполнения, отличном от цикла выполнения по умолчанию, чтобы различать экраны...

person Jan Linxweiler    schedule 17.01.2014
comment
Обратите внимание, что приведенная выше ссылка ведет на форумы разработчиков Apple, которые доступны только при наличии платной учетной записи. - person Uncommon; 22.04.2014

Кроме того, вы можете просто нарисовать выделение в своем представлении вместо того, чтобы говорить с элементом состояния.

- (void)drawRect:(NSRect)dirtyRect
{
    if( active )
    {
         [[NSColor selectedMenuItemColor] set];
         NSRectFill(self.bounds);
    }
}

это отразится как на вашем представлении, так и на клоне.

person Curtis Hard    schedule 06.05.2014
comment
Почему за меня проголосовали, это отличный способ добиться этого. - person Curtis Hard; 13.05.2014