Могу ли я удалить верхнее и нижнее заполнение настраиваемого NSMenu?

Я хочу создать настраиваемое всплывающее меню со светлым текстом на темном фоне. Я знаю setView: метод NSMenuItem, который я мог бы использовать, чтобы каждый элемент рисовал светлым текстом на темном фоне. Однако NSMenu рисует полосы высотой 4 пикселя вверху и внизу меню светлым цветом, что в значительной степени портит внешний вид. Поскольку у NSMenu нет никаких общедоступных методов рисования, которые я мог бы переопределить, я не вижу, как избавиться от этих полос.

Я вижу, что в заголовке NSMenu есть переменные частного экземпляра с именами noTopPadding и noBottomPadding. Так соблазнительно!


person JWWalker    schedule 16.10.2013    source источник


Ответы (1)


Я нашел решение, используя необъявленный метод (очевидно, не идеальный). Сначала объявите это следующим образом:

@interface NSMenu (secret)
- (void) _setHasPadding: (BOOL) pad onEdge: (int) whatEdge;
@end

Затем, перед отображением меню, выполните:

if ([menu respondsToSelector: @selector(_setHasPadding:onEdge:)])
{
    [menu _setHasPadding: NO onEdge: 1];
    [menu _setHasPadding: NO onEdge: 3];
}

Мое тестирование показывает, что это не работает на Snow Leopard, но работает на Lion, Mountain Lion и Mavericks.

person JWWalker    schedule 18.10.2013
comment
Вы также можете использовать это в Swift, если объявите интерфейс (secret) в заголовке Objective-C, который вы включаете в свой промежуточный заголовок - person Dov; 04.11.2014
comment
@Dov, как вы его используете в Swift? Я импортировал заголовок моста, но все еще получаю «использование неразрешенного идентификатора _setHasPadding» - person Saorikido; 31.07.2016
comment
@ Neeson.Z Я не уверен, как бы вы этого достигли, используя решение на 100% Swift, поскольку у вас нет возможности определять заголовок метода без реализации. Лучше всего, вероятно, будет определить категорию выше в заголовке моста (или заголовке, который импортирует заголовок моста). - person Dov; 03.08.2016
comment
В macOS Mojave и более поздних версиях вы получаете меню со светлым текстом на темном фоне, если вы установите темный общий вид приложения. - person JWWalker; 13.11.2019