CATransaction + UIView на iOS 3.2

Мне нужно реализовать очень настраиваемую анимацию в iOS 3.2. Итак, я не могу использовать блочную анимацию или анимацию UIKit до 4.0. Я пытаюсь использовать Core Animation.

Вот мой код:

[CATransaction begin];
[CATransaction setAnimationDuration: 3.0];
[CATransaction setDisableActions: YES];
someView.frame = CGRectMake(endX, 0, endWidth, height); 
// a lot of another property changes
[CATransaction commit];

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

Вот мои попытки:

  • Я установил новый фрейм не для просмотра, а для его слоя (someView.layer.frame = ...) - это было еще хуже, потому что размеры подпредставлений вида не менялись.
  • Я установил для параметра отключения действия значение ДА и НЕТ.

Требования к решению:

  • Должна поддерживаться iOS 3.2 (без блоков).
  • Анимации необходимо применять к разным видам (следовательно, к разным слоям).
  • Кривая анимации достаточно сложна, поэтому я не могу использовать предопределенные кривые анимации (или, на языке CA, MediaTimingFunction).

person QuickNick    schedule 03.07.2012    source источник


Ответы (3)


Опубликованный вами код явно отключает анимацию. Эта строка является виновником:

[CATransaction setDisableActions: YES];

Сделав этот вызов, все изменения, внесенные в вашу транзакцию, будут немедленно зафиксированы, без анимации. Избавьтесь от этой строки, и изменения должны оживить.

Если вам нужна настраиваемая кривая, вы можете использовать CABasicAnimation, как предложил кто-то другой. Действительно, объекты CAAnimation применяются только к одному слою, поэтому вам придется создать несколько объектов CAAnimation.

В качестве альтернативы вы должны иметь возможность использовать метод CATransaction setAnimationTimingFunction и передавать ему настраиваемую функцию синхронизации, которую вы создаете. См. Справку по классу CAMediaTimingFunction. В частности, обратите внимание на метод functionWithControlPoints ::::, который позволяет вам создать функцию синхронизации, указав контрольные точки для кривой Безье, которая описывает вашу функцию синхронизации. Вы ограничены одним кубическим безье, который начинается с 0,0 и заканчивается 1,1. Нет прямой поддержки более сложных функций времени, хотя я видел хаки, которые позволяют добиться более сложных эффектов.

person Duncan C    schedule 04.07.2012

Не уверен, хотите ли вы этого или нет, но вы можете использовать анимацию UIView.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:3.0];
someView.frame = CGRectMake(endX, 0, endWidth, height); 
// a lot of another property changes
[UIView commitAnimations];
person Omar Abdelhafith    schedule 03.07.2012
comment
Кривая анимации слишком сложна, я не могу использовать методы анимации UIView. Я обновил вопрос и добавил требование MediaTimingFunction. - person QuickNick; 03.07.2012

Если вы хотите иметь только настраиваемую функцию времени, вы можете сделать это с помощью CABasicAnimation. Вы можете создать настраиваемую функцию синхронизации (которая представляет собой кривую Безье от (0,0) до (1,1) с двумя контрольными точками, которые вы можете указать.

Если вам этого недостаточно (если вам нужно более двух контрольных точек для вашей функции синхронизации), вам придется использовать CAKeyframeAnumation. Затем вы можете указать сколько угодно значений (используя свойство values (массив).

В обоих случаях вы должны создать объект анимации для «кадра» ключевого пути и добавить анимацию к слою представлений. Обратите внимание, что при явной анимации свойства значение не изменяется, поэтому после анимации te-кадр вернется к исходному значению, если вы одновременно не анимируете и изменяете значение

person David Rönnqvist    schedule 03.07.2012
comment
Да, я думал использовать BasicAnimation, но, как я понял, это применяется к одному слою. Я должен анимировать более одного вида. - person QuickNick; 03.07.2012
comment
Вы можете использовать группу анимации для применения нескольких анимаций к одному и тому же слою, но если вы хотите применить их к разным слоям, вам потребуется транзакция. Хорошая вещь в группах анимации заключается в том, что вы можете настроить их (например, установить время), и это будет применяться ко всем анимациям в этой группе. Однако это не будет работать так хорошо, если вам потребуется анимация по ключевым кадрам. Возможно, у вас может быть метод, который возвращает подходящий массив для вашего значения и обратно, и использовать его, чтобы получить одинаковое время для всех анимаций (если вам нужны ключевые кадры) - person David Rönnqvist; 03.07.2012