Анимация iPhone основана на вводимых значениях (касаниях), а не на времени - PullRequest
12 голосов
/ 18 января 2011

Для анимационного эффекта, идеально подходящего для группового подхода анимации, как показано в Ответ Брэда Ларсона здесь , мне нужно, чтобы анимация продолжалась в соответствии с входными данными. Конкретно касание и положение обнаруженных касаний. Легко обрабатывать touchesMoved: и устанавливать положение элементов для каждого прикосновения, но это не так гладко, как при использовании основного анимационного подхода.

Вообразите мрамор в желобчатом следе. Я хочу подтолкнуть мрамор в любую позицию с любой скоростью в одном или другом направлении. Анимация должна делать что-то подобное, перемещая визуальный элемент по пути в ответ на прикосновения. CAKeyframeAnimation имеет точный бит пути, но, кажется, всегда хочет основывать переход от кадра к кадру по истекшему времени, а не по какому-либо другому фактору и в одном направлении.

31 января, обновление - Спасибо всем за ответы, однако никто не решает проблему. У меня есть круглое меню, которое перетаскивается, чтобы выбрать опцию. Все это должно двигаться вместе, и я обошел его, используя представление, к которому применено вращательное преобразование и обратное вращательное преобразование, примененное к его подпредставлениям, поэтому все значки вращаются с соответствующей ориентацией колеса обозрения. Это действительно выглядит лучше, когда иконки анимированы по слегка овальному пути, хотя ... мраморное описание - это попытка прояснить, что я пытаюсь сделать. Возможно, лучше представить магниты, ориентированные на то, чтобы отталкивать все движение в канавке - двигайтесь один, и его соседи тоже движутся, но не обязательно в направлении, в котором перемещаемый магнит движется по кривой.

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

Ответы [ 5 ]

7 голосов
/ 02 февраля 2011

Вы можете использовать иерархию временных шкал в деревьях слоев для достижения того, что вы ищете. Объекты, реализующие CAMediaTiming, которые включают в себя CAAnimation и CALayer, наследуют пространство времени от своего родителя, которое они могут изменять (посредством масштабирования, сдвига и повторения) и распространять на своих потомков. Установив свойство speed слоя на 0.0 и настроив свойство timeOffset вручную, вы можете отделить этот слой (и все его подслои) от обычного представления о времени.

В вашем случае вы бы задали анимацию для всех элементов меню, чтобы анимировать их положение вдоль желаемого значения CGPath от времени t 0 до t 1 , с соответствующими timeOffset на каждой анимации, чтобы ваши предметы находились на надлежащем расстоянии. Обратите внимание, что beginTime, равное 0,0 для анимации, обычно интерпретируется как начиная с момента добавления анимации к ее слою, поэтому, если вы хотите, чтобы t 0 было 0,0, вы Возможно, придется установить его на крошечный эпсилон> 0.0.

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.beginTime = 1e-100;
animation.duration = 1.0;
animation.fillMode = kCAFillModeBoth;
animation.removedOnCompletion = NO;
animation.path = path;
animation.calculationMode = kCAAnimationPaced;
animation.timeOffset = timeOffset;

Затем вы установите для свойства speed значение 0.0 на родительском слое (содержащем только эти элементы меню) и обновите его timeOffset до значений между t 0 и t 1 в ответ на ваши сенсорные события.

У этого подхода есть два возможных предостережения. Поскольку вы перенимали природу времени в этом поддереве слоя, вы, вероятно, не сможете одновременно анимировать другие свойства. Кроме того, если вам нужно быстрое движение, вам, вероятно, придется анимировать время вперед самостоятельно.

1 голос
/ 23 января 2011

скорость = расстояние / время.Вы можете попробовать, дав задержку в зависимости от перемещенных движений и времени.Вы можете рассчитать время между методами touchesBegan и touchesEnded.

1 голос
/ 18 января 2011

Если вы ориентируетесь на iOS 4.0 или выше, вы можете использовать новые блочные методы класса , чтобы запустить анимируемые изменения вида объектов.Таким образом, из вашего события касания вы можете инициировать анимируемое изменение свойств в представлении:

[UIView animateWithDuration:1.0 animations:^{
    yourView.alpha = 0.0; // fade out yourView over 1 second
}];

NB Это может быть просто изменение другого свойства в представлении, например, егоместо нахождения.Таким образом вы можете анимировать следующие свойства в представлении:

@property frame
@property bounds
@property center
@property transform
@property alpha
@property backgroundColor
@property contentStretch

Если вы нацеливаетесь на более ранние версии iOS, вам нужно будет использовать UIView beginAnimations и commitAnimations Способы создания анимационного блока:

[UIView beginAnimations:nil context:context];
[UIView setAnimationDuration:1.0]; 
yourView.alpha = 0.0;
[UIView commitAnimations];

Этот материал работает очень хорошо, и как только вы начнете его использовать, вам нужно быть осторожным, чтобы не стать зависимым.;)

Обновление для комментария:

Вы можете привязать положение мрамора к месту события касания.Как только вы получите событие touchesEnded , вы можете анимировать местоположение мрамора, используя блок анимации.

0 голосов
/ 27 января 2011

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

Другими словами, в перемещенных касаниях производим расчет скорости с учетомнаправление предыдущей скорости.В конце касания, выстрелите блок, который переводит «мрамор», уменьшая скорость, когда вы отклоняете.Если пользователь снова перемещает мрамор, изменяет локальную переменную, это, в свою очередь, ускоряет анимацию мрамора или замедляет его / меняет направление в зависимости от направления касания.

0 голосов
/ 27 января 2011

Я не совсем уверен, что точно понимаю, что вы хотите сделать, но ... Почему бы просто не нарисовать мрамор там, где находится палец пользователя?Не требуется анимация.Если вы хотите, чтобы мрамор двигался после того, как пользователь отпускает его, вам нужно сохранить концепцию импульса и использовать ее для анимации замедления мрамора.Для этого вы можете использовать CoreAnimation или таймер.

...