Создание подкласса NSView для получения прозрачного фона

Я создаю приложение, в котором мне нужно иметь прозрачный NSView с прозрачным изображением PNG внутри. Проблема в том, что NSView, который я рисую, имеет серый фон. У меня есть подклассы (как TransparentRectangleView), но я не знаю, что добавить в drawRect, чтобы сделать его прозрачным.

Я уже переопределил метод isOpaque, чтобы вернуть NO, но, похоже, это не помогает ...

В качестве альтернативы, существует ли уже подкласс NSView, который похож на UIImageView в iPhone (пока я могу добавлять вложенные представления внутри, мне нужно добавить текст внутри).


person Andrew M    schedule 08.01.2011    source источник
comment
В Интерфейсном Разработчике нет ползунка прозрачности? Кажется, я помню, как случайно уменьшил непрозрачность одного из моих взглядов.   -  person Sam Dufel    schedule 08.01.2011
comment
Я почти на 100% уверен, что устанавливает прозрачность всего вида, включая детей. Это означало бы, что все мои кнопки и текст также будут иметь непрозрачность 1% или что-то еще. Если я ошибаюсь, дайте мне знать: D   -  person Andrew M    schedule 08.01.2011
comment
Подождите, так вам просто нужен прозрачный цвет фона? Я знаю, что для UIViews есть предопределенный прозрачный цвет, который вы можете использовать, хотя я не пробовал использовать его с NSViews.   -  person Sam Dufel    schedule 08.01.2011
comment
Да, я использую Mac, поэтому UIView - это не то же самое, что NSView. В любом случае, решил проблему с FakeImageView   -  person Andrew M    schedule 08.01.2011
comment
@Andrew M, вы ошибаетесь, прозрачность представления не влияет на его дочерние элементы. Виды рисуются независимо друг от друга.   -  person d11wtq    schedule 09.01.2011


Ответы (3)


Чтобы сделать вид прозрачным, просто заполните его [NSColor clearColor].

- (void)drawRect:(NSRect)rect {
    [[NSColor clearColor] set];
    NSRectFill(rect);
}

Реализация isOpaque по умолчанию возвращает NO, поэтому, если вы создаете подкласс NSView, а не какое-либо другое представление, вам не нужно беспокоиться о его переопределении.

person ughoavgfhw    schedule 08.01.2011
comment
Это очень пригодится на будущее! Спасибо! - person Andrew M; 09.01.2011
comment
Между прочим, я вполне уверен, что если вы оставите drawRect: пустым, вы получите тот же эффект, так как вы ничего не будете рисовать. Разумно уверенно = определенно, поскольку я делаю это часто. - person d11wtq; 09.01.2011
comment
Ваш код рисует черный прямоугольник, если вы не установите окно непрозрачным (окно, а не представление! NSView непрозрачны по умолчанию, но NSWindow непрозрачны по умолчанию). См. Также этот текст drissman.com/blog/archives/2009/ 10/09 / Итак, вы хотите либо упомянуть это об окне, либо использовать NSRectFillUsingOperation, как показано в тексте. О, это также будет работать, если ваш вид будет многослойным, поскольку в этом случае у него есть собственный слой для рисования. - person Mecki; 08.12.2016
comment
@Mecki OP, похоже, не спрашивает о том, чтобы сделать все окно прозрачным. Просто вид, чтобы вы могли видеть под ним другие виды. - person ughoavgfhw; 09.12.2016
comment
@ughoavgfhw Кажется, вы не понимаете: ваш код отображается черным цветом, если только окно не настроено на непрозрачность. Не имеет значения, хочет ли OP непрозрачное окно или нет, ваш код работает только с непрозрачным окном. Вы когда-нибудь пробовали свой код по-настоящему? - person Mecki; 09.12.2016
comment
Скопируйте этот код rextester.com/SHLGC62567 в main.m, скомпилируйте с clang -framework Cocoa -o windowtest main.m и запустите с ./windowtest. Вот как выглядит результат: s29.postimg.org/6a4mv566f/so_4635442.png Кажется ли, что верхнее левое окно имеет прозрачный NSView? Неа. Но это именно то, что ваш код делает в непрозрачном окне, если только представление содержимого не является многоуровневым (что не по умолчанию) - person Mecki; 09.12.2016

Принятый ответ у меня не работает, так как мое окно непрозрачно. Как http://www.drissman.com/blog/archives/2009/10/09/nsrectfill_and_nscolor_clearcolor.html (и обсуждение ниже) сказал, что следующие коды работают:

- (void)drawRect:(NSRect)rect {
    [[NSColor clearColor] set];
    NSRectFillUsingOperation(rect, NSCompositeSourceOver);
    // do other drawings
}
person lk_vc    schedule 24.10.2012
comment
SourceOver - это, по большей части, операция компоновки по умолчанию. Это не отличается от [NSBezierPath fillRect:] и одновременно менее эффективно и менее эффективно, чем NSRectFill, который (необычно) использует NSCopyCompositeOperation. И, как говорит d11wtq в принятом ответе, в этом нет необходимости - само представление уже прозрачно, за исключением тех случаев, когда вы рисуете иначе. - person Peter Hosey; 23.04.2013
comment
@PeterHosey Вы хоть читали, что написано в тексте ссылки? Нет, это не то же самое. NSRectFill с прозрачным цветом будет работать только в том случае, если окно не было явно установлено непрозрачным, что вы, конечно, можете сделать, но это тратит много времени на вычисления, если ваше окно на самом деле непрозрачное. NSRectFillUsingOperation будет работать правильно, если окно непрозрачное или нет. Текст по ссылке очень хорошо объясняет это и просто сэкономил мне массу работы. - person Mecki; 08.12.2016

Версия Swift:

override func draw(_ dirtyRect: NSRect) {

    NSColor.clear.set()
    dirtyRect.fill()
}
person sebastienhamel    schedule 24.01.2018