制作平滑的动画入口,退出和交换两个图像视图

时间:2010-11-13 08:51:15

标签: iphone objective-c animation

我正在使用UIView的动画功能将一条鱼的一个图像游到屏幕上,当屏幕中间已经存在一条鱼时,将它游走并开始游泳。鱼的选择是从单独的tableview控制器发送的。

为了实现这一点,我保留了UIImageView的两个实例变量,并在动画完成后为self.fishViewNext交换self.fishViewNext(参见下面的代码)。

我的问题是,在下一条鱼有机会到达之前,用户快速按下新的表格单元格。我的快速解决方案是延迟添加鱼的新消息,此刻什么都不做。这适用于2个快速触摸,但不是更多。我正在寻找想法,如果有人知道如何改进下面的代码,以便动画是平滑的,你可以点击任何最终显示的图像是最后一次点击。这里重要的方法是:

创建第一个图像视图:

- (void) createFish {

self.fishViewCurrent = [[[UIImageView alloc] init] autorelease];
self.fishViewCurrent.contentMode = UIViewContentModeScaleAspectFit;
self.fishViewCurrent.bounds = CGRectMake(0.0f, 0.0f, kFishWidth, kFishHeight);
self.fishViewCurrent.center = CGPointMake(-kFishWidth, kFishYPos); // off the screen to the left
[self addSubview:self.fishViewCurrent];

}

选择tableview单元格时调用的公共方法:

- (void) addFish:(UIImage *)fish {

if (self.fishViewNext) {
    [self performSelector:@selector(addFish:) withObject:(UIImage *)fish afterDelay:1.0];
    return;
}
self.fishViewNext = [[[UIImageView alloc] initWithImage:fish] autorelease];
self.fishViewNext.contentMode = UIViewContentModeScaleAspectFit;
self.fishViewNext.bounds = CGRectMake(0.0f, 0.0f, kFishWidth, kFishHeight);
self.fishViewNext.center = CGPointMake(self.bounds.size.width + kFishWidth, kFishYPos);  // off the screen right
[self addSubview:self.fishViewNext];

[UIView beginAnimations:@"swimFish" context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationBeginsFromCurrentState:YES]; 
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(fishSwamOffHandler:finished:context:)];
[UIView setAnimationRepeatAutoreverses:NO];

self.fishViewNext.center = CGPointMake(self.center.x, kFishYPos); // center
self.fishViewCurrent.center = CGPointMake(-kFishWidth, kFishYPos);  // exit stage left

[UIView commitAnimations];   
}

处理程序将'下一个'鱼(UIImageView)切换为'当前':

- (void)fishSwamOffHandler:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

[self.fishViewCurrent removeFromSuperview]; 
self.fishViewCurrent = self.fishViewNext;
self.fishViewNext = nil;
}

1 个答案:

答案 0 :(得分:1)

最简单的方法是创建一个ivar BOOL,比如_fishIsSwimming,然后_queuedFishView然后更改addFish的开头:看起来像这样:

- (void) addFish:(UIImage *)fish 
{
    // queue the most recent fish, if one was passed in
    if(fish)    
        self.queuedFishView = [[[UIImageView alloc] initWithImage:fish] autorelease];

    // If something is swimming, leave now
    if(_fishIsSwimming)
        return;

    // If we get here and there's no queued fish, leave now
    if(!self.queuedFishView)
        return;

    // We have a queued fish and nothing is swimming, so do the queued fish next 
    // and clear the queued fish
    _fishIsSwimming = YES;
    self.nextFishView = self.queuedFishView;
    self.queuedFishView = nil;
    // Then carry on as normal
}

然后在动画完成回调中,执行以下操作:

-(void) fishSwamOffHandler:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context 
{
    // We're done animating, so ready to do another swimming fish
    _fishIsSwimming = NO;

    [self.fishViewCurrent removeFromSuperview]; 
    self.fishViewCurrent = self.fishViewNext;
    self.fishViewNext = nil;

    // now call to add another fish with nil, so that it will use 
    // the queued fish if there is one and otherwise just early out
    [self addFish:nil];    
}    

所以会发生的事情是你总是在queuedFishView中维护最近传入的鱼,然后一旦动画结束,你可以回到addFish,如果有一条鱼等着去,那么你发送。如果不是,您只需等待按下按钮发送的下一个