views:

22

answers:

1

I have a UIView that in the layoutSubviews method repositions its subviews based on the orientation of the iPad. Within the layoutSubviews method I have a CABasicAniamtion that is supposed to animate the repositioning of the subviews. The animations are set to specific duration but this duration is being ignored and repositioning happens immediately. I know the animations are firing because I am seeing the AnimationDidStart and AnimationDidStop methods being fired. I know this has something to do with the CALayers of the UIView but I can not find anything on the web to explain how to fix this. Any help would be appreciated.

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon

        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconThinPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        //[iconImageView setCenter:iconThinPosition];

        [iconImageView.layer setPosition:iconThinPosition];
        //[iconImageView setTransform: CGAffineTransformIdentity];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textThinPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];        
        [textImageView.layer setPosition:textThinPosition];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconShownPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        [iconImageView.layer setPosition:iconShownPosition];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textShownPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];
        [textImageView.layer setPosition:textShownPosition];
    }
}
+1  A: 

I wonder if it isn't being ignored so much as there is already an animation transaction in progress when your layoutSubviews gets called. One thing you could try to confirm this is to override -didRotateFromInterfaceOrientation and call your layoutSubviews from there. See if your views animate then.

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//    [self layoutSubviews];
    // Give it a second to settle after the rotation and then call
    // layoutSuviews explicitly.
    [self performSelector:@selector(layoutSubviews) withObject:nil afterDelay:1.0f];
}

Another thing to think about is that since you are only animating the position of the UIView's layer, you could use UIView animations instead of explicit animation. Something like:

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconThinPosition];
        [textImageView setCenter:textThinPosition];
        [UIView commitAnimations];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconShownPosition];
        [textImageView setCenter:textShownPosition];
        [UIView commitAnimations];

    }
Matt Long