Когда именно неявная анимация происходит в iOS?

Все и каждая книга утверждают, что в 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 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • (id) actionForLayer: (CALayer *) слой forKey:(NSString *)event{ return nil; }
Другие вопросы по тегам