views:

177

answers:

1

I am applying a CAAnimation to move a toolbar on- and off-screen.

When I touch the superview, that fires the following method:

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [UIView beginAnimations:kViewerToggleToolbarAnimation context:nil];
    if (self.viewerToolbarView.isVisible) {
     self.viewerToolbarView.frame = CGRectMake(0, self.frame.size.height, self.viewerToolbarView.frame.size.width, self.viewerToolbarView.frame.size.height);
     self.viewerToolbarView.isVisible = NO;
    }
    else {
     self.viewerToolbarView.frame = CGRectMake(0, self.frame.size.height - kUIToolbarHeight, self.viewerToolbarView.frame.size.width, self.viewerToolbarView.frame.size.height);
     self.viewerToolbarView.isVisible = YES;
    }
    [UIView commitAnimations];
}

This in turn fires the subview's delegate method:

- (id<CAAction>) actionForLayer:(CALayer *)layer forKey:(NSString *)key {
    id<CAAction> animation = nil;
    if ([key isEqualToString:kViewerToggleToolbarAnimation]) {
     animation = [CABasicAnimation animation];
     if (self.isVisible)
      ((CABasicAnimation*)animation).duration = kViewerToolbarHideAnimationDuration;
     else 
      ((CABasicAnimation*)animation).duration = kViewerToolbarShowAnimationDuration;
     ((CABasicAnimation*)animation).timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
    } 
    else {
     animation = [super actionForLayer:layer forKey:key];
    }
    return animation;
}

The constants kViewerToggleToolbarAnimation, kViewerToolbarHideAnimationDuration and kViewerToolbarShowAnimationDuration are defined elsewhere as:

extern NSString * const kViewerToggleToolbarAnimation;
extern CGFloat const kViewerToolbarShowAnimationDuration;
extern CGFloat const kViewerToolbarHideAnimationDuration;
...
NSString * const kViewerToggleToolbarAnimation = @"kViewerToggleToolbarAnimation";
CGFloat const kViewerToolbarShowAnimationDuration = 2.50f;
CGFloat const kViewerToolbarHideAnimationDuration = 2.75f;

The problem is that I can increase these duration values in the constants file, but the delegate method ignores those durations and applies its own noticeably short duration (0.5 sec, roughly).

2.5 and 2.75 sec are pretty noticeably long times in which the animation would otherwise run, if it was working properly.

What am I doing wrong about firing the animation, which causes these duration constants to be ignored? It otherwise compiles and runs fine, so it doesn't complain about not being able to find the constants.

A: 

Not 100% sure, but if you wrap explicit animation in a transaction (which +beginAnimations:context: implicitly does), it will scale their duration by the duration of the transaction.

Try setting the duration via +setAnimationDuration: in UIView instead inside the transaction block.

millenomi