Как изменить цвет фона NSPopover, включите треугольную часть?
Как я могу изменить цвет фона NSPopover
включить треугольник?
![enter image description here]()
Ответы
Ответ 1
К сожалению, это действительно невозможно. NSPopover не был предназначен для настройки. Если вы хотите полностью настроить внешний вид, лучше всего использовать стороннюю замену NSPopover с открытым исходным кодом, например INPopoverController.
Ответ 2
На самом деле это намного проще, и вам не нужен частный API.
Сделайте корневой вид вашего контроллера вида пользовательским классом
@implementation MyPopoverRootView
-(void)viewDidMoveToWindow
{
NSView * aFrameView = [[self.window contentView] superview];
MyPopoverBackgroundView * aBGView =[[MyPopoverBackgroundView alloc] initWithFrame:aFrameView.bounds];
aBGView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[aFrameView addSubview:aBGView positioned:NSWindowBelow relativeTo:aFrameView];
[super viewDidMoveToWindow];
}
@end
Ваш фоновый вид просто рисует нужный цвет в его границах.
@implementation MyPopoverBackgroundView
-(void)drawRect:(NSRect)dirtyRect
{
[[NSColor whiteColor] set];
NSRectFill(self.bounds);
}
@end
Ответ 3
Swift 3
override func viewDidMoveToWindow() {
guard let frameView = window?.contentView?.superview else {
return
}
let backgroundView = NSView(frame: frameView.bounds)
backgroundView.wantsLayer = true
backgroundView.layer?.backgroundColor = .white // colour of your choice
backgroundView.autoresizingMask = [.viewWidthSizable, .viewHeightSizable]
frameView.addSubview(backgroundView, positioned: .below, relativeTo: frameView)
}
Если вы хотите изменить только цвет фона popover (включая треугольник/стрелку), я решил, что вам не нужно создавать подкласс NSView. Нужный NSView с фоновым цветом должен быть достаточным.
Кроме того, вам не нужно вызывать super.viewDidMoveToWindow()
, потому что его реализация по умолчанию ничего не делает.
Ответ 4
Благодаря Стефану я получил эту работу. Вот быстрая версия кода View. Как уже отмечалось, это должен быть класс для представления View как ваш контент-контент NSPopOver.
class PopoverContentView:NSView {
var backgroundView:PopoverBackgroundView?
override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
if let frameView = self.window?.contentView?.superview {
if backgroundView == nil {
backgroundView = PopoverBackgroundView(frame: frameView.bounds)
backgroundView!.autoresizingMask = NSAutoresizingMaskOptions([.ViewWidthSizable, .ViewHeightSizable]);
frameView.addSubview(backgroundView!, positioned: NSWindowOrderingMode.Below, relativeTo: frameView)
}
}
}
}
class PopoverBackgroundView:NSView {
override func drawRect(dirtyRect: NSRect) {
NSColor.redColor().set()
NSRectFill(self.bounds)
}
}
Ответ 5
У меня возникла та же проблема, но я стараюсь избегать добавления элементов интерфейса сторонних разработчиков в свой проект, поэтому я посмотрел дальше. Кажется, если вы переопределите drawRect:
в представлении вашего popover contentViewController
с настройкой цвета, например:
[[NSColor whiteColor] setFill];
NSRectFill([self bounds]);
тогда у вас будет popover с белым фоном, кроме треугольника/стрелки, которая соединяет его с прямоугольником, к которому он относится. Для решения этого вопроса вам нужно получить доступ к представлению пограничной границы, которое содержит стрелку:
NSView* borderView = [self.view.window valueForKeyPath:@"_borderView"];
Я знаю, что это частный API, но если ваши цели не включают отправку приложения в App Store, это самый простой способ. Теперь вы можете переопределить drawRect:
для этого представления. Чтобы избежать таких проблем, как приватное свойство _borderView
, переименованное с обновлением SDK, я предлагаю утверждать для существования borderView перед его ссылкой.
NSAssert(borderView, @"_borderView does not exist");
Ответ 6
Вот самое легкое решение этой проблемы, которое я нашел. Нет необходимости подклассифицировать NSView или добавлять любые подпрограммы.
NSView *popoverView = [[[[self popover] contentViewController] view] superview];
[popoverView setWantsLayer:YES];
[[popoverView layer] setBackgroundColor:[[NSColor colorWithWhite:0.8 alpha:1] CGColor]];
Получить супервизор корневого представления popover, установить его цвет фона слоя.
Ответ 7
Решение Майка Бедара работает, но добавив еще одну вещь (чтобы получить треугольник, заполненный цветом фона), и это должно переопределить функцию draw внутри PopoverContentView как а также:
override func draw(_ dirtyRect: NSRect) {
backColor.set() // backColor is NSColor
NSRectFill(self.bounds)
}