Пользовательское поле содержимого NSWindow приводит к путанице с маской авторазмера - PullRequest
0 голосов
/ 07 марта 2011

В настоящее время я использую метод, показанный в этой статье «Какао с любовью», для создания собственного подкласса NSWindow. Как и в примере, мне нужно было иметь примерно 10px полей вокруг содержимого окна, чтобы нарисовать стрелку (я создаю окно в стиле popover). У меня должно было быть поле вокруг всего окна, а не только сторона со стрелкой на нем, потому что я хотел иметь возможность изменять положение стрелки, не перемещая содержимое.

Подводя итог, метод, который я использую для этого (соответствующий код внизу):

  • Переопределите методы contentRectForFrameRect: и frameRectForContentRect:styleMask: NSWindow, чтобы добавить отступы вокруг содержимого:
  • Устанавливает пользовательский вид нарисованного фрейма окна как contentView, а затем переопределяет установщик и получатель для contentView, так что переданное представление добавляется как подпредставление объекта вид кадра

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

Layout

Вот как настроена маска автоматического изменения размера представления прокрутки табличного представления:

Table View Autoresizing

А вот как устанавливается маска авторазмера текстовой метки:

Label Autoresizing

А вот как выглядит результат в приложении:

Actual result

Соответствующий код (полученный из вышеупомянутой статьи)

#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 . Включает пример проекта на случай, если вы захотите попытаться воспроизвести проблему.

1 Ответ

1 голос
/ 25 августа 2011
-( void )scaleWindowForHeight:( float )height
{
    if (height > 22)
    {
        NSWindow* window = [self window];
        NSRect old_window_frame = [window frame];
        NSRect old_content_rect = [window contentRectForFrameRect: old_window_frame];
        NSSize new_content_size = NSMakeSize( old_window_frame.size.width, height );
        // need to move window by Y-axis because NSWindow origin point is at lower side:
        NSRect new_content_rect = NSMakeRect( NSMinX( old_content_rect ), NSMaxY( old_content_rect ) - new_content_size.height, new_content_size.width, new_content_size.height );
        NSRect new_window_frame = [window frameRectForContentRect: new_content_rect];
        [window setFrame: new_window_frame  display:YES  animate: [window isVisible] ];
    }
    else
        NSLog(@"window size too small");
}
...