Подтвердить что ты не робот

Когда в 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?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Core Animation - Layer Actions - Определенный шаблон поиска для Action Keys

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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

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

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

Ответ 5

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

Ответ 6

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

  • (id) actionForLayer: (CALayer *) layer forKey: (NSString *) event { return nil; }