Когда именно неявная анимация происходит в iOS? - PullRequest
22 голосов
/ 20 января 2011

Все и каждая книга утверждают, что в CALayer происходят неявные анимации. Тем не менее, каждый раз, когда я хотел проверить, что до сих пор, я получаю жесткую привязку к установленному значению. Нет анимации вообще.

Вот пример в проекте, где больше ничего не происходит. Все, что я делаю, это создаю представление, затем получаю его экземпляр CALayer и делаю что-то, что должно быть неявно анимированным.

[theLayer setValue:[NSNumber numberWithFloat:M_PI * 1.1] forKeyPath:@"transform.rotation.z"];

Еще один:

CGRect currentBounds = theLayer.bounds;
currentBounds.size.width += 120.f;
[self.animatedLayer setBounds:currentBounds];

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

Значит, либо все эти книги неверны и имеют в виду старые знания Mac OS X при написании Core Animation и неявных анимаций, либо я делаю что-то не так. Кто-нибудь может привести рабочий пример, демонстрирующий неявную анимацию на iPhone?

Ответы [ 6 ]

65 голосов
/ 20 января 2011

UIKit отключает неявную анимацию. Чтобы быть более конкретным, CALayer, связанный с UIView, никогда не будет неявно анимировать. CALayers, которые вы создаете сами и которые не связаны с UIView, перейдут на обычный неявный механизм анимации.

Если вам интересно, как это работает, неявные анимации происходят после обычного -actionForKey: lookup. Если для данного свойства есть CAAction, оно используется. В противном случае используется неявная анимация. В случае CALayer, связанного с UIView, UIView реализует метод делегата -actionForLayer:forKey:, а когда его нет в анимационном блоке UIView, он всегда возвращает [NSNull null], чтобы указать, что поиск действия должен остановиться здесь. Это предотвращает работу неявных анимаций. Внутри блока анимации UIView он создает собственное действие для представления текущих настроек анимации UIView. Опять же, это предотвращает неявную анимацию.

Если вам нужно анимировать свойства CALayer, которые UIView не будет делать для вас, вы можете использовать явный подкласс CAAnimation (например, CABasicAnimation).

2 голосов
/ 07 июня 2011

Старая запись, но ссылка ниже указывает на раздел в Руководстве по программированию основной анимации, который помогает пролить немного света на то, что говорил Кевин Баллард. В действительности должно быть явное примечание, в котором упоминается, что для того, чтобы анимировать свойства нижележащего слоя UIView, необходимо убедиться, что вы установили делегат слоя для экземпляра, который примет метод actionForLayer: ForKey: и вернет nil. Было обнаружено, что вы также можете установить делегата для экземпляра, который не принимает этот метод, и он по-прежнему допускает неявную анимацию, но это неаккуратная и запутанная практика.

Основная анимация - Действия слоя - Определенный шаблон поиска для клавиш действий

1 голос
/ 01 апреля 2014

Это в точности правильный ответ Кевина Балларда. Я хочу предоставить что-то еще здесь.

Подробная информация из официального документа

Есть раздел под названием: Правила изменения слоев в iOS, и вы найдете

Класс UIView отключает анимации слоев по умолчанию, но включает их внутри блоков анимации.

За исключением включения неявного в блоке анимации UIView. Есть два других решения:

  1. Сделайте слой, который вам нужен, анимацию, подслой вида. Обратитесь к [ответ] [2]

    [2]: Анимации неявных свойств не работают с CAReplicatorLayer? Неявное постепенное появление анимации не работает. Я попробовал это, это работало как ожидалось.

  2. назначить делегата слоя самому слою. По умолчанию делегатом уровня в iOS является его представление резервного хранилища, которое реализует слой actionForLayer: (id) для ключа forKey: (NSString *) и возвращает [NSNull null], чтобы отключить неявную анимацию слоя.
1 голос
/ 22 февраля 2012

Имейте в виду, что подслои первичного слоя UIView обычно не имеют UIView в качестве своего делегата. Следовательно, они участвуют в неявной анимации, если вы явно не заблокируете это, даже если вы не предоставили делегата для возврата действия nil в ответ на actionForLayer: forKey:.

Итак, один простой способ получить неявную анимацию в общем виде - это просто добавить подуровень, который покрывает основной слой.

Книга Мэтта Нойберга «Программирование iOS 5» (в настоящее время находится на стадии бета-тестирования в Safari Books Online) объясняет эту тему очень доходчиво.

0 голосов
/ 18 января 2016

На самом деле, вы можете просто вернуть nil, чтобы получить анимацию CALay по умолчанию.

  • (id) actionForLayer: (CALayer *) слой forKey: (NSString *) event { вернуть ноль; }
0 голосов
/ 21 апреля 2011

Вы также можете установить делегат слоя для вашего собственного объекта и обработать -actionForLayer: forKey :. Похоже, вы получаете неявную анимацию, даже если делегат не реализует -actionForLayer: forKey:.

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