Принудительно перерисовывать пользовательский контроль какао при изменении свойства - PullRequest
4 голосов
/ 23 августа 2010

Допустим, у меня есть пользовательский элемент управления, называемый FooBox.Это просто квадрат на экране.У него есть некоторые свойства, такие как цвет, граница и т. Д. Когда я изменяю свойства, я хочу, чтобы FooBox перерисовывал себя, отражая его новые свойства.Есть ли способ сделать это без написания пользовательских сеттеров и добавления [self setNeedsDisplay: YES] во все из них?

Ответы [ 5 ]

5 голосов
/ 23 августа 2010

Я не уверен, что это правильный способ сделать это, но вы можете рассмотреть возможность использования NSKeyValueObserving и зарегистрировать объект в качестве наблюдателя самого себя, а также выполнить перерисовку в методе -observeValueForKeyPath:ofObject:change:context:.

2 голосов
/ 23 августа 2010

РЕДАКТИРОВАТЬ: Питер прав в комментариях, это решение работает, только если для этого свойства зарегистрирован наблюдатель. Теперь я помню, что я сделал это на CALayer со свойствами @dynamic, и в этом случае это работает так, как вы хотели бы. Однако в общем случае это не очень хорошее решение вашей проблемы.

Предполагая, что ваш класс совместим с KVC для свойств, для которых вы хотите вызвать повторное отображение, я бы переопределил метод -didChangeValueForKey: для вызова [self setNeedsDisplay], когда ключ соответствует одному из ваших свойств. Я думаю, что это немного лучше, чем метод переопределения Питера -setValue: forKey: потому что он не мешает нормальному механизму KVC и не требует бокса, который он упоминает.

- (void)didChangeValueForKey:(NSString*)key {
    if ([@"propertyOne" isEqualToString:Key] ||
        ....) {
        [self setNeedsDisplay];
    }
    [super didChangeValueForKey:key]; // <- Don't forget this
}
1 голос
/ 23 августа 2010

Два других способа:

  1. Иметь то, что отправляет просмотр сообщения доступа, отправьте ему setNeedsDisplay:YES сразу после. Не всегда возможно, и не меньше хлопот.
  2. Переопределите setValue:forKey:, чтобы добавить к нему сообщение setNeedsDisplay:, и используйте его для установки свойств представления. Это потребует объединения любых числовых или структурных значений, которые обменивают одну стычку на другую.

Итак, по сути, нет.

0 голосов
/ 27 июля 2011

Если свойства изменены с помощью NSControl, вы всегда можете поместить

[theView setNeedsDisplay:YES]

в действие, отправленное NSControl.

0 голосов
/ 23 августа 2010

Я не знаю ни одного. Я бы написал себе несколько макросов, чтобы добиться цели, если это меня достаточно обеспокоило

...