NSView Не обновляется?
-
15-09-2020 - |
Вопрос
Я работаю над представлением перетаскивания и нашел в Интернете несколько обработчиков для действий перетаскивания.Я хочу сделать так, чтобы он становился синим, когда пользователь перетаскивает файл в область перетаскивания, и снова серым, когда он выходит из области перетаскивания.Проблема в том, что он не обновляется, когда вы наводите на него указатель мыши или выходите из него.Вот часть кода:
- (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];
}
Спасибо за любую помощь.
Решение
Рисование работает только тогда, когда для вас настроен контекст (например, холст для рисования).Когда фреймворк вызывает -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:
, поэтому вам следует делать это всякий раз, когда что-то меняется.В вашем случае это, вероятно, означает, что мышь входит или выходит из области перетаскивания.