Вызов setNeedsDisplay: YES в представлении размещения слоев не перерисовывает представление - PullRequest
8 голосов
/ 06 сентября 2010

У меня настроен вид размещения хоста, подобный этому, в пользовательском подклассе NSView:

[self setLayer:rootLayer];
[self setWantsLayer:YES];

Я добавляю все подслои в дерево слоев после того, как я вызвал setNeedsDisplay на каждом подслое. Содержимое каждого слоя предоставляется методом drawLayer:inContext делегата моего слоя.

Вот моя проблема:

После инициализации моего вида вид становится нарисованным правильно. Однако, когда модель изменилась, и я звоню [myCustomView setNeedsDisplay:YES]; с моего контроллера представления, drawLayer:inContext не вызывается.

Я запутался, как обновить вид:

  • Нужно ли вызывать метод setNeedsDisplay для каждого CALayer в дереве слоев?
  • Не должен ли вызов setNeedsDisplay:YES в самом представлении размещения слоев вызвать перерисовку всего дерева слоев?

Спасибо за вашу помощь.

Редактировать

Я нашел что-то в справочнике класса NSView

Представление на основе слоя - это представление, которое поддерживается слоем Core Animation. Любой рисунок, сделанный представлением, кэшируется в резервном слое. Вы настроили представление на основе слоев, просто вызвав setWantsLayer: со значением YES. Класс представления автоматически создаст для вас вспомогательный слой, и вы используете механизмы рисования класса представления. При использовании представлений со слоем вы никогда не должны напрямую взаимодействовать со слоем.

Представление размещения слоя - это представление, содержащее слой Core Animation, которым вы намерены манипулировать напрямую. Вы создаете представление размещения слоя, создавая экземпляр класса слоя Core Animation и устанавливая этот слой с помощью метода viewLayer :. После этого вы вызываете setWantsLayer: со значением YES. При использовании вида размещения слоев вы не должны полагаться на вид для рисования и не должны добавлять подпредставления в представление размещения слоев.

ссылка на документацию

В моем случае у меня есть вид размещения слоя. Так значит ли это, что мне придется вручную перерисовывать? Должен ли я реализовать псевдо-метод drawRect в пользовательском NSView для вызова соответствующего setNeedsDisplay на CALayers, который изменился?

Ответы [ 2 ]

10 голосов
/ 06 сентября 2010

После дальнейших исследований в образце кода Apple меню в стиле киоска я обнаружил, что если вы используете представление размещения слоев, вы должны позаботиться об обновлениях экрана, которые необходимы в модель меняет себя. Вызов setNeedsDisplay:YES в NSView ничего не даст.

Итак, что нужно сделать, если нужно обновить представление, следует написать метод, такой как reloadData, и в нем нужно вызвать setNeedsDisplay для каждого CALayer, который нуждается в обновлении. Я все еще не уверен, будет ли вызов этого метода на корневом уровне распространяться на все дочерние слои, но я так не думаю.

Теперь я решил проблему, вызвав setNeedsDisplay для отдельных слоев CALay, которые нуждались в повторении. Работает без проблем.

2 голосов
/ 25 октября 2012

Существует также часто используемая практика наличия пустого «ничьего», например -(void) drawRect:(NSRect)dirtyRect {}, чтобы помочь принуждать вещи к рисованию, я верю через хороший оле view.needsDisplay = YES;

и следует отметить, что на самом деле происходит следующее: если вы говорите, что NSView *view; равен layer.delegate = view;, то слой рисуется, когда вызывается [layer setNeedsDisplay]; .... через - (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {...} ..

в том же духе ... при произнесении layer.layoutManager = view ... последующие требования, что [layer setNeedsLayout]; будет выполняться только при реализации метода - (void) layoutSublayersOfLayer:(CALayer *)layer {..} ..

Эти жизненно важные понятия скрыты в документах Apple ... и они действительно настолько важны, чтобы заставить абсолютно все работать вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...