0

如果我想为 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

4 回答 4

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];
}
于 2012-05-04T14:07:37.520 回答
2

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

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

CoreAnimation 有几个怪癖,在 WWDC 2010 和 WWDC2011 视频中进行了解释。他们有很好的材料,他们解释了一些不是很明显的技巧。

话虽如此,在 UITableView 中为单元格设置动画是一件复杂的事情,因为您实际上是在研究 UITableView 的内部结构,因此会出现各种奇怪的副作用。您可以从 TweetStation 中提取执行该动画并处理各种极端情况的代码。但即使是 TweetStation 和 iOS 版 Twitter 应用程序也无法做到完美,因为您在 UIView 背后制作动画,而 UIView 会不断更新和更改您正在制作动画的相同属性。

于 2011-10-27T15:02:04.883 回答
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/

于 2011-10-26T19:11:48.063 回答
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");
于 2011-10-26T20:00:12.210 回答