NSView Не обновляется?

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

- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];
   [[NSColor grayColor] set];
   [NSBezierPath fillRect:bounds];
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender  {
    NSRect bounds = [self bounds];
    [[NSColor blueColor] set];
    [NSBezierPath fillRect:bounds];

    return NSDragOperationCopy;

}

- (void)draggingExited:(id <NSDraggingInfo>)sender {
    NSRect bounds = [self bounds];
    [[NSColor grayColor] set];
    [NSBezierPath fillRect:bounds];

}

Спасибо за любую помощь.

2 ответа

Решение

Рисование работает только тогда, когда для рисования установлен контекст (например, холст для рисования). Когда структура вызывает -drawRect: он установил контекст рисования для вас, поэтому команды рисования, такие как -[NSColor set] а также -[NSBezierPath fillRect:] работать как вы ожидаете.

Вне -drawRect: обычно контекст рисования не настроен. Использование команд рисования вне -drawRect: это как размахивать кистью в воздухе; там нет холста, поэтому картина не происходит.

В 99,99% случаев все виды рисунка должны быть в пределах -drawRect: потому что NSView выполняет большую часть работы, которую вы не хотите выполнять, чтобы правильно и эффективно настроить контекст рисования.

Итак, как вы можете изменить рисунок вашего представления в вашем -draggingEntered: а также -draggingExited: методы? По побочным эффектам.

Вы делаете одно и то же во всех трех случаях: 1) установка цвета и 2) рисование прямоугольника. Разница лишь в изменении цвета в каждом методе. Итак, почему бы не контролировать, какой цвет вы используете в -drawRect: с помощью ивара, вот так:

- (void)draggingEntered:(id <NSDraggingInfo>)sender {
    drawBlueColorIvar = YES;
    // ...
}

Затем в -drawRect: ты делаешь это:

- (void)drawRect:(NSRect)rect {
    NSColor *color = drawBlueColorIvar ? [NSColor blueColor] : [NSColor grayColor];
    [color set];
    [NSBezierPath fillRect:rect];
}

(Обратите внимание, я не использовал [self bounds], Более эффективно просто рисовать в "грязный" прямоугольник, когда это возможно.)

Наконец, вам нужен какой-то способ сообщить платформе, что ваше представление должно перерисовываться при изменении drawBlueColorIvar. Фреймворк не будет ничего рисовать, пока не будет сказано, что это необходимо. Как сказал Крис Купер, вы делаете это с [self setNeedsDisplay:YES], Это должно идти после любого места, которое вы меняете drawBlueColorIvar,

Ты звонишь [yourView: setNeedsDisplay] в любом месте?

Это то, как вы даете рамке рисования знать, что она должна сообщать вашему UIView подкласс с drawRect:так что вы должны делать это всякий раз, когда все изменилось. В вашем случае это, вероятно, означает, когда мышь входит или выходит из области перетаскивания.

Другие вопросы по тегам