В настоящее время я использую метод, показанный в этой статье «Какао с любовью», для создания собственного подкласса NSWindow. Как и в примере, мне нужно было иметь примерно 10px полей вокруг содержимого окна, чтобы нарисовать стрелку (я создаю окно в стиле popover). У меня должно было быть поле вокруг всего окна, а не только сторона со стрелкой на нем, потому что я хотел иметь возможность изменять положение стрелки, не перемещая содержимое.
Подводя итог, метод, который я использую для этого (соответствующий код внизу):
- Переопределите методы
contentRectForFrameRect:
и frameRectForContentRect:styleMask:
NSWindow, чтобы добавить отступы вокруг содержимого:
- Устанавливает пользовательский вид нарисованного фрейма окна как
contentView
, а затем переопределяет установщик и получатель для contentView
, так что переданное представление добавляется как подпредставление объекта вид кадра
Проблема в том, что автоматически изменяемые маски представлений внутри реального представления содержимого окна полностью запутаны. Вот как я настраиваю контент в конструкторе интерфейсов:
Вот как настроена маска автоматического изменения размера представления прокрутки табличного представления:
А вот как устанавливается маска авторазмера текстовой метки:
А вот как выглядит результат в приложении:
Соответствующий код (полученный из вышеупомянутой статьи)
#define CONTENT_MARGIN 10.0
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
windowFrame.origin = NSZeroPoint;
return NSInsetRect(windowFrame, CONTENT_MARGIN, ICONTENT_MARGIN);
}
- (NSRect)frameRectForContentRect:(NSRect)contentRect
{
return NSInsetRect(contentRect, -CONTENT_MARGINT, -CONTENT_MARGIN);
}
+ (NSRect)frameRectForContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
{
return NSInsetRect(contentRect, -CONTENT_MARGIN, -CONTENT_MARGIN);
}
- (NSView*)contentView
{
return _popoverContentView;
}
- (void)setContentView:(NSView *)aView
{
if ([_popoverContentView isEqualTo:aView]) { return; }
NSRect bounds = [self frame];
bounds.origin = NSZeroPoint;
SearchPopoverWindowFrame *frameView = [super contentView];
if (!frameView) {
frameView = [[[SearchPopoverWindowFrame alloc] initWithFrame:bounds] autorelease];
[super setContentView:frameView];
}
if (_popoverContentView) {
[_popoverContentView removeFromSuperview];
}
_popoverContentView = aView;
[_popoverContentView setFrame:[self contentRectForFrameRect:bounds]];
[_popoverContentView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[frameView addSubview:_popoverContentView];
}
Я подумал, что, возможно, контент поповера каким-то образом выходит за рамки, поэтому я нарисовал границу вокруг просмотра контента, но нет, все так, как должно быть. Единственная проблема заключается в том, что маски авторазмера метки и табличного представления внутри представления содержимого не работают должным образом. Любой совет с благодарностью.
РЕДАКТИРОВАТЬ: Если кому-то интересно, я с открытым исходным кодом полный код для этого всплывающего окна / контроллера на github, как INPopoverController . Включает пример проекта на случай, если вы захотите попытаться воспроизвести проблему.