Анимации представлений в iOS

Небольшая заметка о том, как анимировать изменение представлений в iOS.

В приложениях для iOS принято уделять внимание взаимодействию с пользователем. Это касается из изменения элементов интерфейса. Чаще всего изменения более очевидны для пользователя, если они происходят с анимацией. Например, если нужно переместить кнопку, освобождая место для нового элемента, хорошо будет показать это движение.
Анимации не должны быть целью, они не должны занимать много времени, однако отказываться от них совсем не стоит. Кроме того, некоторые стандартные элементы управления (например, UINavigationController, UISwitch) используют анимации.

Начиная с iOS 4, рекомендуется использовать методы анимации, использующие блоки. Именно о них мы и поговорим.

Методы анимации класса UIView

+ (void)animateWithDuration:(NSTimeInterval)duration 
                      delay:(NSTimeInterval)delay 
                    options:(UIViewAnimationOptions)options 
                 animations:(void (^)(void))animations 
                 completion:(void (^)(BOOL finished))completion;

+ (void)animateWithDuration:(NSTimeInterval)duration 
                 animations:(void (^)(void))animations 
                 completion:(void (^)(BOOL finished))completion;

+ (void)animateWithDuration:(NSTimeInterval)duration 
                 animations:(void (^)(void))animations;

+ (void)transitionWithView:(UIView *)view 
                  duration:(NSTimeInterval)duration 
                   options:(UIViewAnimationOptions)options
                animations:(void (^)(void))animations 
                completion:(void (^)(BOOL finished))completion;

+ (void)transitionFromView:(UIView *)fromView 
                    toView:(UIView *)toView 
                  duration:(NSTimeInterval)duration 
                   options:(UIViewAnimationOptions)options 
                completion:(void (^)(BOOL finished))completion;

На самом деле, здесь две основных групп методов – анимация изменения представлений и анимация замены одного представления другим.
Первые три метода отличаются только набором параметров (первый – наиболее подробный метод, третий – самый простой, большая часть параметров не задается).

Памаетры методов +animateWith...:

  • duration – длительность анимации в секундах;
  • delay – задержка перед началом анимаций в секундах;
  • options – битовая маска настроек анимации (описание настроек будет чуть ниже);
  • animations – блок анимаций, в нем вы указываете финальное значение анимируемых свойств;
  • completion – блок, вызываемый по завершению анимации, параметр finished указывает, были ли анимации завершены или были прерваны; можно передавать NULL в качестве значения.

Самое интересное в анимации представлений в iOS – метод анимации хоть и должен вызываться в основном потоке, но не будет блокировать выполнение, он завершится сразу же. Более того, после вызова метода все свойства, заданные в блоке animations будут иметь свои финальные значения. Анимация будет происходить асинхронно, не блокируя интерфейс приложения.

Более того, вызовы анимации могут происходить в то время, когда предыдущая анимация еще не завершилась. И тогда, анимации будут скомбинированы. Пользователь увидит анимацию представления, которая объединяет все действия. Управлять объединением анимаций можно с помощью настроек (см. ниже).
Таким образом, для программиста анимация – это лишь небольшая обертка вокруг его действий по изменению свойств представления. Все остальное берет на себя фреймворк.

Еще один важный момент – анимации осуществляются над копией представления. Графическая подсистема использует картинку с состоянием представления до начала анимации и создает картинку с финальным внешним видом, а затем создает анимацию между этими двумя графическими образами. Таким образом, для анимации не нужно перерисовывать представление. В некоторых случаях, представления нужно перерисовывать программно при анимации, для этого есть соответствующая настройка (см. ниже).

Примеры анимаций:

UIView *view = ...;

// move view
[UIView animateWithDuration:0.5
                 animations:^{
                     view.center = CGPointMake(view.center.x + 10.0f, view.center.y + 10.0f);
                 }];

// make view disappear
[UIView animateWithDuration:0.5
                 animations:^{
                     view.alpha = 0.0f;
                 }
                 completion:^(BOOL finished) {
                     [view removeFromSuperview];
                 }];

Метод +transitionWithView:duration:options:animations:completion: служит для анимированного изменения иерархии дочерних представлений представления view. Остальные параметры аналогичны предыдущим методам.
Данным методом вы также можете комбинировать изменения в иерархии (добавлять и удалять дочерние предствления) с изменениями свойств представления (в этом случае необходимо указать опцию UIViewAnimationOptionAllowAnimatedContent).

Метод +transitionFromView:toView:duration:options:completion: чуть-чуть более простой – он позвляет анимировать замену одного представления другим (исходное представление будет также удалено из своего родительского представления, а новое будет добавлено в него). Параметры этого метода таковы:

  • fromView – представление, которое будет удалено из своего родительского представления;
  • toView – представление, которое будет добавлено вместо fromView;
  • duration – длительность анимации в секундах;
  • options – битовая маска настроек анимации (описание настроек будет чуть ниже);
  • completion – блок, вызываемый по завершению анимации, параметр finished указывает, были ли анимации завершены или были прерваны; можно передавать NULL в качестве значения.
UIView *cardFace = ...;
UIView *cardBack = ...;

// switch card back to face
// (cardBack will be removed from superview, cardFace will be added)
[UIView transitionFromView:cardBack
                    toView:cardFace
                  duration:0.5
                   options:UIViewAnimationOptionTransitionFlipFromLeft 
                completion:NULL];

Настройки анимации
Общие настройки анимации:

  • UIViewAnimationOptionLayoutSubviews – дочерние представления будут изменены вместе с изменениями родителя;
  • UIViewAnimationOptionAllowUserInteraction – позволяет пользователю взаимодействовать с представлением во время анимации (иначе, действия с представлениям будут невозможны во время анимации);
  • UIViewAnimationOptionBeginFromCurrentState – настройка позволяет начать новую анимацию во время действия предыдущей и продолжить изменение значений свойств с их текущих значений (например, если перемещение представления не было завершено, то анимация продолжится не с финальной точки, а с той, где представление находилось на экране);
  • UIViewAnimationOptionRepeat – бесконечно повторять анимации;
  • UIViewAnimationOptionAutoreverse – по завершении анимации автоматически анимированно возвращать представление к исходному состоянию (необходимо указывать совместно с UIViewAnimationOptionRepeat);
  • UIViewAnimationOptionOverrideInheritedDuration – позволяет использовать длительность действующей анимации, если запрос был сделан в то время, когда представление уже анимируется предыдущим запросом;
  • UIViewAnimationOptionOverrideInheritedCurve – позволяет “унаследовать” скорость анимации (см. ниже) от предыдущего запроса анимации;
  • UIViewAnimationOptionAllowAnimatedContent – говорит фреймворку, что анимация изменений представления требует перерисовывать его (если ен указывать эту опцию – изменения свойств анимируются над сохраненным растровым изображением для ускорения процесса);
  • UIViewAnimationOptionShowHideTransitionViews – позволяет вместо добавления и удаления представлений показывать и скрывать их (эту опцию нужно указать, если вы хотите анимаировать замену представлений без их удаления из родительского представления).

Настройки скорости анимации:

  • UIViewAnimationOptionCurveEaseInOut – анимация ускоряется в начале и замедляется к концу;
  • UIViewAnimationOptionCurveEaseIn – анимация ускоряется в начале, затем скорость анимации не меняется;
  • UIViewAnimationOptionCurveEaseOut – анимация идет с постоянной скоростью, но в конце она замедляется;
  • UIViewAnimationOptionCurveLinear – скорость анимации не меняется.

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

Свойства перехода (замены) представлений:

  • UIViewAnimationOptionTransitionNone – замена представления не анимируется;
  • UIViewAnimationOptionTransitionFlipFromLeft – представление “переворачивается” вокруг вертикальной оси слева направо;
  • UIViewAnimationOptionTransitionFlipFromRight – представление “переворачивается” вокруг вертикальной оси справа налево;
  • UIViewAnimationOptionTransitionCurlUp – представление “загибается” наверх (как лист блокнота);
  • UIViewAnimationOptionTransitionCurlDown – представление “разгибается” сверху (как лист блокнота);
  • UIViewAnimationOptionTransitionCrossDissolve – представление “растровяется” в новом;
  • UIViewAnimationOptionTransitionFlipFromTop – представление “переворачивается” вокруг горизонтальной оси сверху вниз;
  • UIViewAnimationOptionTransitionFlipFromBottom – представление “переворачивается” вокруг горизонтальной оси снизу вверх.

Свойства UIView, изменения которых можно анимировать: frame, bounds, center, transform, alpha, backgroundColor. Дочерние классы могут определять новые свойства, которые также можно анимировать. Стоит обратиться к документации класса, чтобы узнать, какие из свойств можно анимировать.

Как обычно, стоит почитать документацию Apple.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s