UIView重新出现时如何恢复动画?

时间:2014-02-01 01:46:56

标签: ios uiview ios7 core-animation

我有一个自定义UIView子类(ValveStatusView)。它是一个放置在自定义'UITableViewCell subclass (ValveCell) . Upon receiving awakeFromNib in ValveStatusView`中的子视图,我设置了许多子图层,其中一个是动画的。动画设置代码如下所示:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(32, 64 + 6)];
    animation.duration = 0.75;
    animation.repeatCount = HUGE_VALF;
    animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
[drop addAnimation:animation forKey:@"position"];

它使得“掉落”的图像永远地从水龙头反复掉落。这些单元格嵌入UITableView,然后嵌入标签视图中。当我导航到另一个选项卡,然后返回时,我的动画不再运行了。我假设当包含我的视图的视图堆栈不再映射到窗口时,它会关闭动画。这是正确的假设吗?假设它是,当视图再次映射时,什么是让它再次运行的惯用方法?

我查看了UIView方法,但没有任何东西跳出来作为明显的“钩子”让它再次运行。我承认会浏览它们,而不是详尽地阅读它们。

3 个答案:

答案 0 :(得分:6)

您应该在问题中提到包含动画图层的视图是UITableViewCell的子类。 :)因为,这实际上是动画停止的原因。 UITableViewCell从其子图层中删除动画,以避免在从tableview中删除单元格以供以后重用时进行不必要的计算。要解决您的问题,您可以覆盖单元格的prepareForReuse方法并在那里重新启动动画。所以你应该做这样的事情:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

        // some initial setup here...

        [self addAnimation];
    }
    return self;
}

- (void)prepareForReuse {

    [super prepareForReuse];

    [self addAnimation];
}

- (void)addAnimation {

    // remove previous animations
    [drop removeAllAnimations];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(32, 64 + 6)];
    animation.duration = 0.75;
    animation.repeatCount = HUGE_VALF;
    animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
    [drop addAnimation:animation forKey:@"position"];
}

希望这有帮助。

答案 1 :(得分:1)

尝试将代码放在- (void) viewWillAppear:方法而不是awakeFromNib中,这样只要显示视图就会触发它。

修改

好的,我现在看到,你可以使用NSNotificationCenter

来做到这一点

在customCell的awakeFromNib中添加一个观察者:

- (void) awakeFromNib
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(startAnimation:)
                                                     name:@"addAnimation"
                                                   object:nil];
    }
  • startAnimation:方法中,您当然会使用动画代码。
  • 在您的UITableViewController的viewWillAppear中,您发布通知以重新启动动画。

    [[NSNotificationCenter defaultCenter]         postNotificationName:@ “addAnimation”         对象:自];

  • 在CustomCell中的某个位置,您必须删除观察者,否则将永远不会卸载该单元格。

答案 2 :(得分:1)

我原来的问题措辞不明显。我尝试过编辑来澄清情况。无论是否UITableViewCell遏制,我的愿望是找到一种对此漠不关心的解决方案。封装等等。

以下代码已添加到ValveStatusView(我的UIView的子类)。

- (void) didMoveToWindow {
    if (self.window != nil) {
        [self startDropAnimation];
    }
}

诀窍。 startDropAnimation的灵感来自上面@Davlat建议的重构:

- (void)startDropAnimation {
    CALayer* drop = self.activeFaucet.sublayers.firstObject;
    [drop removeAllAnimations];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(32, 64 + 6)];
    animation.duration = 0.75;
    animation.repeatCount = HUGE_VALF;
    animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
    [drop addAnimation:animation forKey:@"position"];
}

didMoveToWindow是我正在寻找的钩子(我想)。