改变正在进行的动画

基本上,我试图做的是动画云,然后改变它的速度和/或方向中动画,如果风的变化。 如果它很重要,我从UIViewController控制整个事物,并且在云端存在一个带有CALayer的UIView,这就是云本身。 我也尝试过使用UIImageView。

对于TL:DR类型,简而言之,我要做的是要么获得动画视图的位置,要么停止使用块动画的动画视图。

这里是完整的故事。 我的问题是在动画期间得到它的位置。 我正在使用块动画。 因为我只知道它应该移动的速度,所以我需要使用剩下的距离来计算自己的时间。 我已经尝试了下面的代码和它的几个变体:

[[Cloud CloudImage]convertPoint:CGPointMake([[[Cloud CloudImage] presentationLayer] position].x, 0) toLayer:self.layer].x

Cloud是UIView,CloudImage是CALayer。 这是我尝试过的最复杂的变体,我尝试了各种更简单的变体(例如直接询问Cloud,或者用UIView代替CALayer)。 但是,它返回的只是它的最终价值。 我读了一些关于这个方法的内容,从3.2中断开,但是在4.2中被修复; 但是,当我将部署目标更改为iOS 4.3而不是4.0时,它并未得到解决。 我正在使用4.3基地sdk。

我考虑过的其他一些变化是将动画全部停止片刻,然后立即获取位置并开始新动画。 但是,我需要知道一种方法来阻止基于块的动画,并且我只找到旧的动画系统(commitanimations)的片段。

我考虑的最后一个是写我自己的动画系统; 云会有0.08秒左右的重复NSTimer,并且每次发射时都会创建一个0.08秒的核心动画,为此它使用给予云的速度作为属性。 然而,我担心任何这种变化都会有更低的性能,而我需要它尽可能轻量级,因为我同时拥有多达20个这样的云(有时也会下雨)。

提前致谢!


在这种情况下,我肯定会推出自己的系统,并且使用CADisplayLink而不是NSTimerCADisplayLink直接绑定到屏幕更新计时器),可以将性能损失与使用内置动画代码的性能损失降至最低。

事实上,您同时拥有20个云并不会真正改变事情,因为我认为您的意图是使用内置的动画分别为这20个云制作动画。

如果你不确定性能有多大,最终会对事情产生什么影响,你可以尝试使用内置动画简单地添加一堆云(50个左右),看看它们是如何缓慢移动的,然后切换它到内置的动画代码并进行比较。

编辑:关于堆栈溢出的这个讨论详细介绍了如何去做你所问的,以防你走这条路线:取消一个UIView动画?

例:

// startAnimating called once to initiate animation loop. might be stopped e.g. 
// if game is paused or such
- (void)startAnimating
{
    // displayLink = the CADisplayLink for the current animation, if any.
    if (displayLink) {
        [displayLink invalidate]; 
        [displayLink release];
    }

    displayLink = [[CADisplayLink displayLinkWithTarget:self
                                               selector:@selector(animationTick:)] 
                   retain];

    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

// tick method is called at every interval; we want to update things based on 
// a delta time (duration), so that if things get bogged down and the updates 
// come less often, we don't go into slow motion
- (void)tick:(CADisplayLink *)sender
{
    CFTimeInterval duration = sender.duration;
    // here, we update the position for all the UIView objects. example:
    CGRect cloudFrame;
    for (UIView *cloud in clouds) {
        cloudFrame = cloud.frame;
        cloudFrame.origin.x += windForceX * duration;
        cloudFrame.origin.y += windForceY * duration;
        cloud.frame = cloudFrame;
    }
    // here we might update the windForceX and Y values or this might happen somewhere
    // else
}
链接地址: http://www.djcxy.com/p/39489.html

上一篇: Changing a ongoing animation

下一篇: How to create custom easing function with Core Animation?