views:

331

answers:

1

So I'm currently testing out the UIView animations, and I noticed that the shadows rendered by CALayer (using [view.layer setShadowStuffHere]) disappear at the start of the animation and reappear at the end of the animation. Is there any way I can keep these shadows and have the shadows animate along with the UIView? I tried using shadows without border paths, but that was a terrible idea, since the frame rate dropped like a rock during the animation, and I didn't get shadows anyways.

The code I'm using right now is below. Initially you see a red view, and when tapped, it'll flip over into a larger blue view. The end result should be something similar to the iPad music app; when an album is selected, it flips over to reveal a view on the backside.

- (void)viewDidLoad {
    [super viewDidLoad];

    UITapGestureRecognizer * tapRec;

    // Drop shadow Path creation
    CGFloat x1 = 0;
    CGFloat y1 = 0;
    CGFloat x2 = 100;
    CGFloat y2 = 100;

    frontBorderPath = CGPathCreateMutable();
    CGPathMoveToPoint(frontBorderPath, NULL, x1, y1);
    CGPathAddLineToPoint(frontBorderPath, NULL, x2, y1);
    CGPathAddLineToPoint(frontBorderPath, NULL, x2, y2);
    CGPathAddLineToPoint(frontBorderPath, NULL, x1, y2);
    CGPathAddLineToPoint(frontBorderPath, NULL, x1, y1);

    x2 = 400;
    y2 = 400;
    backBorderPath = CGPathCreateMutable();
    CGPathMoveToPoint(backBorderPath, NULL, x1, y1);
    CGPathAddLineToPoint(backBorderPath, NULL, x2, y1);
    CGPathAddLineToPoint(backBorderPath, NULL, x2, y2);
    CGPathAddLineToPoint(backBorderPath, NULL, x1, y2);
    CGPathAddLineToPoint(backBorderPath, NULL, x1, y1);

    containerView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    containerView.clipsToBounds = NO;
    [containerView.layer setShadowPath:frontBorderPath];
    [containerView.layer setShadowOpacity:1];
    [containerView.layer setShadowOffset:CGSizeMake(0,0)];
    [containerView.layer setShadowRadius:3];
    [containerView.layer setShouldRasterize:NO];
    [self.view addSubview:containerView];

    tapRec = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(frontTap)] autorelease];
    frontView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    frontView.backgroundColor = [UIColor redColor];
    [frontView addGestureRecognizer:tapRec];
    [containerView addSubview:frontView];

    tapRec = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backTap)] autorelease];
    backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)];
    backView.backgroundColor = [UIColor blueColor];
    [backView addGestureRecognizer:tapRec];    
}

- (void)frontTap{
    NSLog(@"fronttap");

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.7];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:containerView cache:YES];

    [frontView removeFromSuperview];
    [containerView addSubview:backView];
    containerView.frame = CGRectMake(100, 100, 400, 400);
    [containerView.layer setShadowPath:backBorderPath];

    [UIView commitAnimations];

}

- (void)backTap{
    NSLog(@"backtap");

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.7];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:containerView cache:YES];

    [backView removeFromSuperview];
    [containerView addSubview:frontView];
    containerView.frame = CGRectMake(100, 100, 100, 100);
    [containerView.layer setShadowPath:frontBorderPath];

    [UIView commitAnimations];

}
+1  A: 

It turns out that when you're doing a UIView animation, it ignores your view's clipsToBounds property and clips it anyways (at least for the flip type animations), so if you want your shadows to always be visible, you'll need to have a view frame large enough that contains everything.

David Liu