弹跳式动画。当您将它应用于同一财产时

时间:2011-10-26 16:50:36

标签: ios animation uitableview xamarin.ios uianimation

如果我想为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 个答案:

答案 0 :(得分:12)

这是一篇很好的文章,解释了如何让它反弹。

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];
}

答案 1 :(得分:2)

您的方法存在的问题是UIView.Animate会记录您对视图所做的更改,但只记录它们的最终状态。

如果在动画块中更改了Bounds属性一百次,则只有最后一个属性是从动画框架的角度来看的重要属性。

CoreAnimation有一些在WWDC 2010和WWDC2011视频中解释的怪癖。他们有很棒的材料,他们解释了一些不太明显的技巧。

话虽如此,在UITableView中设置动画细胞是一件很复杂的事情,因为你真的在寻找UITableView内部,所以期待各种奇怪的副作用。您可以从执行该动画的TweetStation中提取代码并处理各种角落案例。但即便是TweetStation和Twitter for iOS应用程序也不会是完美的,因为你在UIView的背后动画,不断更新和改变你动画的相同属性。

答案 2 :(得分:0)

从头脑中,最简单的方法是将动画代码放入方法中,并根据需要随时调用递归方法。代码未经测试,但它应该起作用或至少给你一个想法。

// 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/

答案 3 :(得分:0)

缺乏文档和良好的样本有时甚至会使简单的任务变得非常具有挑战性。

这是解决方案

当然代码不优雅,但它确实有效。希望有一天能帮助其他人,所以他或她不需要花半天时间来完成像这样简单的事情

var activeCell = ((Element)sender).GetActiveCell();

var animation = 
 (CAKeyFrameAnimation)CAKeyFrameAnimation.FromKeyPath ("transform.translation.x");
animation.Duration = 0.3;

animation.TimingFunction = // small details matter :)
          CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut.ToString()); 

animation.Values = new NSObject[]{
                                   NSObject.FromObject (20), 
                                   NSObject.FromObject (-20),
                                   NSObject.FromObject (10),
                                   NSObject.FromObject (-10),
                                   NSObject.FromObject (15),
                                   NSObject.FromObject (-15),
                                 };

activeCell.Layer.AddAnimation (animation,"bounce");