Question

When implementing UIView animateWithDuration:animations:completion: Class method, I encountered with a scenario I couldn't figure our how to handle.

I have a UIImageView that moves across the screen. Upon a certain event, it should change direction, and move to a new position. But(!) It seems that if this event happens, instead of just changing directions and moving to the new position, it 'jumps' to the original 'end position' and begin moving to the new position from there.

I'm not sure how I can instruct the 'moving object', upon completion == NO, to capture its current position and start animating from there, instead of jumping to the predetermined end position.

Here is the code:

- (IBAction)goHere:(UIButton *)sender
{
    CGPoint movingEndPoint;
    if ( sender == self.btn1 )
    {
        movingEndPoint = CGPointMake( sender.center.x + 40, sender.center.y + 40 );
    }
    if ( sender == self.btn2 )
    {
        movingEndPoint = CGPointMake( sender.center.x - 40, sender.center.y - 40 );
    }

    [UIView animateWithDuration:3
                     animations:^ {
        self.movingObj.center = movingEndPoint;
    }
                     completion:^(BOOL completion) {
                         if (completion == NO)
                         {
                             //How to express "New Position = Current Position"?
                         }
                     }];
}
Was it helpful?

Solution 2

Instead of doing it in completion block, add this code in your event before giving new position.

Lets say you event method is eventMethod,

your modified code should be

[UIView animateWithDuration:5
                     animations:^ {
                         self.movingObj.center = CGPointMake(400, 400); //old final position
                     }
                     completion:^(BOOL completion) {

                     }];

-(void)eventMethod{
    _movingObj.frame =[_movingObj.layer.presentationLayer frame];
    [UIView animateWithDuration:2
                     animations:^ {
                         self.movingObj.center = CGPointMake(0, 0); //new final position
                     }
                     completion:^(BOOL completion) {

                     }];
}

OTHER TIPS

This behavior has been remedied in iOS 8 (where it picks up the new animation using the object's current position and direction), but in earlier iOS versions, the easiest fix is to use the rendition of animateWithDuration with the options parameter, and include the UIViewAnimationOptionBeginFromCurrentState option.

Alternatively, you can use the view's layer's presentationLayer to get the current position mid-animation. For example,

CALayer *layer = self.movingObj.layer.presentationLayer;
CGRect currentFrame = layer.frame;

You can then set then stop the animations (e.g. [self.movingObj.layer removeAllAnimations]) and then set the frame of the view using this currentFrame before initiating the next animation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top