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