开发者

Is it possible to successful animate a moving UIButton?

I'm trying to animate a button which moves around the screen. At any point, the user can push the button. But the button doesn't respond to touches. I've tried an animation block but the button simply moves immediately to its end coordinates, while the frame shows the animation (the button is called bubble):

[UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:5.0];
    CGAffineTransform newTransform = CGAffineTransformMakeScale(3, 3);
    bubble.transform = CGAffineTransformTranslate(newTransform, 0, -460);
    [UIView commitAnimations];

So then I tried Core Animation with the help of some sample code (the path isn't important, it's just an example):

CGMutablePathRef thePath = CGPathCreateMutable();
    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);
    CAKeyframeAnimation *theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
    theAnimation.path=thePath;
    CAAnimationGroup *theGroup = [CAAnimationGroup animation];
    theGroup.animations=[NSArray arrayWithObject:theAnimation];
    theGroup.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    theGroup.duration=15.0;
    CFRelease(thePath);
    [bubble.layer addAnimation:theGroup forKey:@"animatePosition"];

But the buttons still don't respond to touches. Btw, I have several of these 'bubble' buttons on screen at once so having several NSTimers concurrently active wouldn't be optimal.

Can anyone suggest another approach? Should I perhaps a开发者_运维百科nimate UIImageViews and make them repsond to touches? Or will I have the same problem? This has been puzzling me for a couple of days so any help much appreciated.

Thanks :)

Michael


When animating a GUI element like the UIButton, the actual position only changes when the animation is done. This means any touch events during the animation will only work at the starting point of the button. You can get the current displayed position of the button by accessing it's presentationLayer. You'll probably need to implement your own event handling, look at the position when the user touches the screen, and compare that to the bounds you get from the presentationLayer.


Well, for anyone interested, here's my solution which works perfectly well:

- (void)startMinigame {
    makeBubbles = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(generateRandomBubble) userInfo:nil repeats:YES];
    floatBubbles = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(floatBubbles) userInfo:nil repeats:YES];
}

- (void)generateRandomBubble {
    //Get a random image for the bubble
    int randomIndex = arc4random()%kNumberBubbles;
    UIImage *bubbleImage = [bubbleImages objectAtIndex:randomIndex];

    //Create a new bubble object and retrieve the UIButton
    Bubble *bubble = [[Bubble alloc]initWithImage:bubbleImage andIndex:randomIndex];
    UIButton *bubbleButton = bubble.bubbleButton;

    //Configure the button
    [bubbleButton addTarget:self action:@selector(bubbleBurst:) forControlEvents:UIControlEventTouchDown];

    //Add the bubble to the scene
    [self.view insertSubview:bubbleButton belowSubview:bathTub];
    //Add the bubble to an array of currently active bubbles:
    [self.bubbles addObject:bubble];
    [bubble release];
}

- (void)floatBubbles {
    //Move every active bubble's frame according to its speed. 
    for (int i = 0; i < [bubbles count]; ++i) {
        Bubble *bubble = [bubbles objectAtIndex:i];
        int bubbleSpeed = bubble.speed;
        CGRect oldFrame = bubble.bubbleButton.frame;
        CGRect newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y - bubbleSpeed, oldFrame.size.width+0.1, oldFrame.size.height+0.1);
        bubble.bubbleButton.frame = newFrame;
        if (bubble.bubbleButton.frame.origin.y < -100.0) {
            [bubbles removeObject:bubble];
            [bubble.bubbleButton removeFromSuperview];
        }
    }
}


This sounds a bit too complicated for UIKit and CoreAnimation. It seems like you're developing something like a game. Why not use a global animation timer for let's say ~60 fps and do your drawing in Quartz2D? Then for each touch you could quickly check any hits between Quartz refreshes.


Try animating the uiview's frame property.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜