Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 动画完成块运行过快_Ios_Objective C_Animation_Recursion_Completion Block - Fatal编程技术网

Ios 动画完成块运行过快

Ios 动画完成块运行过快,ios,objective-c,animation,recursion,completion-block,Ios,Objective C,Animation,Recursion,Completion Block,我试图在用户定义的路径上移动飞机,类似于飞行控制中的控件。我能够绘制路径,尽管效率很低,但无法使平面沿路径平滑地设置动画 我最初尝试使用通过更改位置提供的隐式动画沿路径移动平面,但因为它不允许我更改动画的速度,所以平面的行为很糟糕 我现在尝试递归地使用动画块,但是完成块被调用得太快,导致平面只是沿着正在绘制的路径 这是设置代码: - (CALayer *)plane{ if(!_plane){ _plane = [CALayer layer]; UIIma

我试图在用户定义的路径上移动飞机,类似于飞行控制中的控件。我能够绘制路径,尽管效率很低,但无法使平面沿路径平滑地设置动画

我最初尝试使用通过更改位置提供的隐式动画沿路径移动平面,但因为它不允许我更改动画的速度,所以平面的行为很糟糕

我现在尝试递归地使用动画块,但是完成块被调用得太快,导致平面只是沿着正在绘制的路径

这是设置代码:

- (CALayer *)plane{
    if(!_plane){
        _plane = [CALayer layer];
        UIImage *planeImage = [UIImage imageNamed:@"airplane.png"];
        _plane.bounds = CGRectMake(20.0, 20.0, planeImage.size.width, planeImage.size.height);
        _plane.contents = (id)(planeImage.CGImage);
        [self.layer addSublayer:_plane];
    }
    return _plane;
}
- (void)touchesEnded:(NSSet *)touches
           withEvent:(UIEvent *)event{
    if(isDrawingPath){
        [self.trackPath addLineToPoint:[[touches anyObject] locationInView:self]];
        NSLog(@"%@", self.trackPath);

        UITouch *touch = [touches anyObject];
        CGPoint toPoint = [touch locationInView:self];
        //now, save each point in order to make the path
        [self.points addObject:[NSValue valueWithCGPoint:toPoint]];
        [self setNeedsDisplay];
        [self goToPointWithIndex:0];
    }
    isDrawingPath = NO;
}
这个实现很有效,但效果很差。飞机沿着路径飞行,但颠簸起伏:

- (void)goToPointWithIndex:(NSNumber *)indexer{
    int toIndex = [indexer intValue];

    if(toIndex < self.points.count){
        //extract the value from array
        CGPoint toPoint = [(NSValue *)[self.points objectAtIndex:toIndex] CGPointValue];
        CGPoint pos = self.plane.position;
        float delay = PLANE_SPEED * (sqrt( pow(toPoint.x - pos.x, 2) + pow(toPoint.y - pos.y, 2)));
        self.plane.position = toPoint;

        // Allows animation to continue running
        if(toIndex < self.points.count - 1){
            toIndex++;
        }

        //float delay = 0.2;
        NSLog(@"%f", delay);
        //repeat the method with a new index
        //this method will stop repeating as soon as this "if" gets FALSE
        NSLog(@"index: %d, x: %f, y: %f", toIndex, toPoint.x, toPoint.y);
        [self performSelector:@selector(goToPointWithIndex:) withObject:[NSNumber numberWithInt:toIndex] afterDelay:delay];
    }
}
-(void)goToPointWithIndex:(NSNumber*)索引器{
int-toIndex=[indexer-intValue];
如果(toIndex<自点计数){
//从数组中提取值
CGPoint-toPoint=[(NSValue*)[self.points-objectAtIndex:toIndex]CGPointValue];
CGPoint pos=自身平面位置;
浮动延迟=平面速度*(sqrt(功率(拓扑点x-位置x,2)+功率(拓扑点y-位置y,2));
self.plane.position=toPoint;
//允许动画继续运行
如果(toIndex
这就是我试图用积木做的。它只是跳到绘制的路径的末端,而不是跟随整个路径

- (void)goToPointWithIndex:(int)toIndex{
    if(self.resetPath) return;
    //extract the value from array
    if(toIndex < self.points.count) {
        CGPoint toPoint = [(NSValue *)[self.points objectAtIndex:toIndex] CGPointValue];
        NSLog(@"index: %d, x: %f, y: %f", toIndex, toPoint.x, toPoint.y);
        CGPoint pos = self.plane.position;
        //float delay = PLANE_SPEED * (sqrt( pow(toPoint.x - pos.x, 2) + pow(toPoint.y - pos.y, 2)));

        // Allows animation to continue running
        if(toIndex < self.points.count - 1){
            toIndex++;
        }

        [UIView animateWithDuration:0.2
                     animations:^{
                         self.plane.position = toPoint;
                     }
                completion:^(BOOL finished) {
                    if(finished == YES) {NSLog(@"Complete");[self goToPointWithIndex:toIndex];}
        }];
    }
}
-(void)goToPointWithIndex:(int)toIndex{
if(self.resetPath)返回;
//从数组中提取值
如果(toIndex<自点计数){
CGPoint-toPoint=[(NSValue*)[self.points-objectAtIndex:toIndex]CGPointValue];
NSLog(@“索引:%d,x:%f,y:%f”,toIndex,toPoint.x,toPoint.y);
CGPoint pos=自身平面位置;
//浮动延迟=平面速度*(sqrt(功率(拓扑点x-位置x,2)+功率(拓扑点y-位置y,2));
//允许动画继续运行
如果(toIndex
我不知道哪里出了问题。我不熟悉objective-c和blocks。完成块应该在动画开始后立即运行吗?这对我来说毫无意义,但这是我能找到的唯一解释



编辑:我最终使平面成为UIView,这样我仍然可以使用块动画。CALayer事务根本不喜欢我的递归。

因为这里的
self.plane
是一个自定义
CALayer
(与支持
UIView
的层相反),它将不考虑
UIView animateWithDuration:

从:

自定义层对象忽略基于视图的动画块参数,而使用默认的核心动画参数


相反,使用
cabasicanitation
CALayer的
addAnimation:forKey:
方法(在本例中可能使用
CAAnimationGroup
)。如何像这样设置
CALayers
的动画,在文档中的部分中有描述。为什么您只覆盖触摸?然后,对于屏幕上的任何手指路径,您将只拾取一个点。在我看来,你应该覆盖touchesMoved,也许TouchesBegind也应该覆盖(并做与touchesEnded差不多的事情)。

我自己不是一个游戏开发者,但我认为类似cocos2d的东西更适合你的任务。我可能错了,但我只是不认为CoreAnimations是为这样的任务而设计的,至少不是干净的。我也在覆盖其他两个。由于动画效果不佳,我将begin动画调用it Touchs置于结束状态,以便更好地观看
出现在所有触摸方法中,但
[self goToPointWithIndex:0]仅在
触摸键中删除
?我想这应该行得通。