Is it possible to successful animate a moving UIBu

2020-02-11 09:07发布

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 animate 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

4条回答
Summer. ? 凉城
2楼-- · 2020-02-11 09:32

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.

查看更多
老娘就宠你
3楼-- · 2020-02-11 09:35

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.

查看更多
走好不送
4楼-- · 2020-02-11 09:40

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];
        }
    }
}
查看更多
孤傲高冷的网名
5楼-- · 2020-02-11 09:42

Try animating the uiview's frame property.

查看更多
登录 后发表回答