iphone – 改变正在进行的动画

基本上,我想要做的是为云动画,然后在风变化时改变动画中的速度和/或方向.如果重要的是,我从UIViewController控制整个事情,云存在一个UIView,其上面有一个CALayer,这就是云本身.我也尝试过UI ImageView.

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

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

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

Cloud是UIView,CloudImage是CALayer.这是我尝试过的最复杂的变化,我尝试了各种更简单的变体(例如,直接询问云,或者使用UIView而不是CALayer).但是,它返回的只是它的最终值.我读了一些关于这个方法从3.2中被破坏的东西,但在4.2中被修复了;但是,当我将部署目标更改为iOS 4.3而不是4.0时,它没有修复.我正在使用4.3 base sdk.

我考虑的一些其他变化是暂时停止动画片刻,然后立即获得位置并开始新动画.但是,我需要知道一种在其轨道中停止基于块的动画的方法,并且我只找到了旧动画系统的片段(commitanimations).

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

提前致谢!

在这种情况下,我绝对会推出自己的系统,使用CADisplayLink而不是NSTimer(CADisplayLink直接绑定到屏幕更新计时器)可以最大限度地减少使用内置动画代码的性能损失.

你同时拥有20个云的事实并没有真正改变太多的东西,因为我认为你的意图是使用内置的动画分别为这20个云制作动画.

如果你不确定它最终会对性能产生多大的影响,你可以尝试使用内置的动画添加一堆云(大约50个),看看它们移动的缓慢程度,然后切换它out to内置动画代码和比较.

编辑:关于Stack Overflow的讨论详细介绍了如何做你要问的事情,以防你走这条路:Cancel a UIView animation?

例:

// 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
}
相关文章
相关标签/搜索