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