Какао - Пользовательский NSView в NSMenuItem не будет рисовать - PullRequest
3 голосов
/ 02 марта 2011

У меня есть собственный NSView, который раньше создавался в NIB и назначался в качестве представления для NSMenuItem, который прекрасно работает, но теперь я хочу создать представление в коде (по уважительной причине, я могу вас заверить), который сделалне выглядит сложным, но вид на самом деле не отрисовывается.

Сообщение «drawRect:», которое ранее вызывалось для отрисовки вида при необходимости, больше не вызывается, даже когда я отправляю сообщение «setNeedsDisplay:».

Я запускаю вид с изображением и устанавливаю размер (вида, соответствующий размеру изображения), который, кажется, работает, поскольку пункт меню имеет правильный размер, но изображение отсутствует.

Что здесь может происходить?

Это код для инициации представления:

-(id)initWithImage:(NSImage*)image
{
    self = [super init];

    if (self != nil)
    {
        self.imageToDisplay = image;

        // this bit does get called and resizes the view to match the image size
        NSRect imageBounds = NSMakeRect(0.0f, 0.0f, imageToDisplay.size.width, imageToDisplay.size.height);     
        [self setBounds:imageBounds];
        [self setFrame:imageBounds];

        [self setHidden:NO];
        [self setAlphaValue:1.0f];

        [self setAutoresizesSubviews:YES];
    }

    return self;
}

А это код для рисования вида, который не вызывается

// this is never called
-(void)drawRect:(NSRect)dirtyRect
{
    if (imageToDisplay == nil)
        return;

    NSRect imageBounds = NSMakeRect(0.0f, 0.0f, imageToDisplay.size.width, imageToDisplay.size.height);

    [self setBounds:imageBounds];
    [self setFrame:imageBounds];

    [imageToDisplay drawInRect:[self bounds]
                      fromRect:imageBounds
                     operation:NSCompositeSourceAtop
                      fraction:1.0f];
}

И это код для пункта меню, который добавляет представление.

-(void)awakeFromNib
{
    MyCustomView* view = [[MyCustomView alloc] init];

    [self setView:view];

    // i would have expected the image to get drawn at this point
    [view setNeedsDisplay:YES];
}

1 Ответ

1 голос
/ 13 марта 2011

Вам нужно установить frame вашего представления, прежде чем вы сможете установить bounds. В вашем -init... либо поменяйте местами два вызова set..., либо удалите setBounds: (bounds по умолчанию установлен на {(0,0), (frame.size.width, frame.size.height)}), и все должно работать. Я также не думаю, что вам нужно снова устанавливать frame и bounds в drawRect, и фактически кажется плохой идеей менять их, когда фокус уже зафиксирован на вашем виде; в лучшем случае это вызовет странное мигание, если значения на самом деле отличаются.

ОБНОВЛЕНИЕ: только что увидел эту заметку в Просмотр руководства по программированию :

Примечание : если приложение явно устанавливает прямоугольник границ представления, используя любой из методов setBounds ..., изменение прямоугольника рамки представления больше не приводит к автоматическому изменению прямоугольника границ. См. " Расположение и изменение размеров представлений " для получения подробной информации.

...