Анимация отказов типа.Когда вы применяете его к тому же свойству - PullRequest
0 голосов
/ 26 октября 2011

Если я хочу анимировать UITableViewCell, чтобы он несколько раз подпрыгивал слева направо, как я могу это сделать? Я пытаюсь это:

var bounds = activeCell.Bounds;
var originalLocation = bounds.Location;
var loc = originalLocation;

UIView.Animate(0.2,()=>{
   loc.X = originalLocation.X + 20;
   activeCell.Bounds = new RectangleF (loc, bounds.Size);   
   loc.X = originalLocation.X - 20;
   activeCell.Bounds = new RectangleF (loc, bounds.Size);   
});

Он анимирует только последнее состояние (т.е. перемещает элемент влево). Я пытался поместить их в отдельные Animate блоки - это не помогло. Пробовал использовать разные UIAnimationOptions - тоже самое.

Ответы [ 4 ]

12 голосов
/ 04 мая 2012

Вот хорошая статья, объясняющая, как заставить ее отскочить.

http://khanlou.com/2012/01/cakeyframeanimation-make-it-bounce/

Более того, есть объяснение формуле, используемой для вычисления пути отскока.Для личного пользования я взял абсолютное значение вычисления, чтобы имитировать отскок на земле.

- (void) displayNoCommentWithAnimation{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.duration = 2;

int steps = 120;
NSMutableArray *values = [NSMutableArray arrayWithCapacity:steps];
double value = 0;
float e = 2.71;
for (int t = 0; t < steps; t++) {
    value = 210 - abs(105 * pow(e, -0.025*t) * cos(0.12*t));
    [values addObject:[NSNumber numberWithFloat:value]];
}
animation.values = values;

animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.delegate = self;
[viewThatNeedToBounce.layer addAnimation:animation forKey:nil];
}


- (void) animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
CAKeyframeAnimation *keyframeAnimation = (CAKeyframeAnimation*)animation;
[viewThatNeedToBounce.layer setValue:[NSNumber numberWithInt:210] forKeyPath:keyframeAnimation.keyPath];
[viewThatNeedToBounce.layer removeAllAnimations];
}
2 голосов
/ 27 октября 2011

Проблема с вашим подходом состоит в том, что UIView.Animate будет записывать изменения, которые вы вносите в свое представление, но только их конечное состояние.

Если вы сто раз измените свойство Bounds в своем анимационном блоке, только последний из них будет иметь значение с точки зрения анимации.

CoreAnimation имеет несколько причуд, которые объясняются в видеороликах WWDC 2010 и WWDC2011. У них отличный материал, и они объясняют некоторые хитрости, которые не очень очевидны.

При этом, анимация ячеек в UITableView - сложный вопрос, потому что вы действительно изучаете внутренности UITableView, поэтому ожидайте различных странных побочных эффектов. Вы можете снять код с TweetStation, который выполняет эту анимацию и работает с различными угловыми случаями. Но даже TweetStation и приложение Twitter для iOS не могут быть идеальными, потому что вы анимируете вещи за спиной UIView, который постоянно обновляет и вносит изменения в те же свойства, которые вы анимируете.

0 голосов
/ 27 октября 2011

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

Вот решение

Конечно, код не элегантный, но он работает.Надеюсь, это когда-нибудь поможет кому-то другому, поэтому ему или ей не придется тратить полдня на что-то глупо простое, как это

0 голосов
/ 26 октября 2011

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

// Repeat 10 times, move 20 right and the left and right etc.
FancyAnim(activeCell, activeCell.Bounds.Location, 10, 20);

private void FancyAnim(UITableViewCell activeCell, PointF originalLocation, int repeat, float offset)
{
var bounds = activeCell.Bounds;
var loc = originalLocation;

UIView.Animate(0.2,
delegate
{
  // Called when animation starts.
   loc.X = originalLocation.X + offset;
   activeCell.Bounds = new RectangleF (loc, bounds.Size);   
},
delegate
{
  // Called when animation ends.
 repeat--;
// Call the animation method again but invert the movement.
// If you don't do this too often, you should not run out of memory because of a stack overflow. 
if(repeat >= 0)
{
  FancyAnim(activeCell, originalLocation, repeat, -offset);
}
});

Однако вы также можете использовать анимацию пути.Вы должны определить путь «20 единиц справа, назад к центру, 20 единиц слева, назад к центру» и повторять эту анимацию так часто, как вам нравится.Это требует от вас иметь дело с CAKeyFrameAnimation и будет немного больше кода.Этот сайт поможет вам начать: http://www.bdunagan.com/2009/04/26/core-animation-on-the-iphone/

...