Search code examples
iosobjective-ccore-animation

iOS Affine rotation working just once


I have a Button that I would like to use for open/close a view...

It is an arrow, when opening, the arrow will rotate 180°.

And when closing, it should rotate back 180°.

However, it only rotates once while opening, but then on closing won't rotate again. Further more if I open it for a second time, it won't rotate again even if it did the first time.

Here's the code :

    - (id)initWithFrame:(CGRect)frame
    {
        mediaOpened = NO;
        media   = [UIButton buttonWithType:UIButtonTypeCustom];
        [media retain];
        [media setBackgroundImage:[ImageController getImageNamed:@"arrow.png"] forState:UIControlStateNormal];
        [media addTarget:self action:@selector(toggleMedia) forControlEvents:UIControlEventTouchUpInside];
        media.frame = CGRectMake(2, 10, 26, 17);
        [self addSubview:media];
    }

    -(void) rotateMedia {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:0.3];

        float   angle = M_PI;
        media.transform = CGAffineTransformMakeRotation(angle);

        [UIView commitAnimations];
    }

    -(void) mediaClicked {
        if (self.delegate != nil) 
            [self.delegate mediaClicked];

        [self rotateMedia];
    }

    -(void) mediaUnclicked {    
        if (self.delegate != nil)
            [self.delegate mediaUnClicked];

        [self rotateMedia];
    }

    -(void) toggleMedia {
        if (!mediaOpened)
            [self mediaClicked];
        else
            [self mediaUnclicked];
        mediaOpened = !mediaOpened;
    }

Solution

  • Add the line:

    media.transform = CGAffineTransformIdentity; // Add this line to reset from current angle
    media.transform = CGAffineTransformMakeRotation(angle);
    

    before applying the rotation. This will make the rotation from the current position otherwise you are always starting from the same position. What you are doing is rotating to that angle and after it has gone to that angle the successive animation are trying to animate to a position it is already at thus, no animation.