在uiview中创建动画圆和矩形

时间:2014-04-26 00:04:06

标签: objective-c uiview drawing shapes

我必须在我的iphone应用程序(使用xcode)的uiview中创建一些动画形状,就像这些(circlerectangle) 第一个应该是一个增加和减少半径的圆,从0到x,反之亦然;第二个是一个矩形,其长度从0增加到x,反之亦然。形状应无限制动...直到用户点击某个按钮以在某个时刻停止动画。我如何实现这些特定的绘制和动画?实现这一目标的最佳方法是什么?以及如何阻止他们? 非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

在我的情况下,我必须为我的UIView对象的子视图的移动设置动画,我完成了这样的操作:将连续动画分解为逻辑部分,为部件设置动画并配置此动画以在完成动画后启动另一个动画。下面你会看到我的代码原样(它的作用是移动在给定角度沿着该圆放置在圆上的子视图)。

- (void) animatePart: (NSString*) animationId finished: (NSNumber*) finished context: (void *) context
{
    // the context contains an NSNumber which is the angle remaining to turn the pieces
    CGFloat displacement = [trackSet currentDisplacementOnTrack:drag.trackIndex];
    NSMutableDictionary* contextDict = (NSMutableDictionary*) context;
    Move * move = (Move *) [contextDict objectForKey:ANIMCTX_MOVE];
    //NSNumber *direction = (NSNumber *) [contextDict objectForKey:ANIMCTX_DIRECTION];
    printf("> EVC animatePart: displ: %3.3f ",  displacement);
    if (FABS(displacement) < 0.1) {
        printf(", ending animation\n");
        // this is the last piece of animation
        [trackSet completeMoveOnTrack:move.trackRef];
        [self updatePiecesAnimatedFromModel];
        self.animationContext = nil;
    }
    else {
        CGFloat dir = displacement == 0 ? 0 : displacement / FABS(displacement);
        CGFloat delta = -ANIM_DELTASTATION * dir;
        printf(" EVC animatePart: delta: %3.3f\n", delta);
        CGFloat newDelta = FABS(delta) < FABS(displacement) ? delta : -displacement;
        [trackSet registerMoveOnTrack:drag.trackIndex by:newDelta];
        [UIView beginAnimations:animationId context:context];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(animatePart:finished:context:)];
        [self updatePiecesFromTrack:drag.trackIndex];
        [UIView commitAnimations];  

    }
    printf("< EVC animatePart\n");
}

如您所见,UIView方法setDelegate:和animationDidStopSelector:用于配置此动画以在完成动画后调用某个方法。这里传递的选择器是同样的方法。这听起来像一个递归方法(它甚至有一个停止条件,就像递归方法通常那样),但事实并非如此。所以不用担心堆栈溢出;-) 为了完整起见,为了启动这个动画,我使用下面的方法(从我的代码中逐字复制)。

- (void) animateMove: (Move *) move direction: (int) direction
{
    printf("> EVC animateMove: %d\n", direction * move.stations);
    NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObject:move forKey:ANIMCTX_MOVE];
    [dict setObject:[NSNumber numberWithInt: direction] forKey:ANIMCTX_DIRECTION];
    self.animationContext = dict;

    //[trackSet openMoveOnTrack:move.trackRef];
    // the move has already been carried out in the model, but is not yet reflected in the UI
    // we don't need to call trackSet's openMoveOnTrack and closeMoveOnTrack
    // for the animation we initially set the track's current displacement to that of the move
    // then in a series of animated steps we decrement that displacement gradually to zero,
    // while showing the intermediate results in the UI.
    CGFloat moveDisplacement = (CGFloat) (move.stations);
    [trackSet registerMoveOnTrack:move.trackRef by:moveDisplacement];
    [self animatePart:@"displacementAnimation" finished:[NSNumber numberWithInt:0] context:dict];
    printf("< EVC animateMove: \n");
}