I'm trying to copy Apple's behavior in video playback that allows the user to stretch the video image to fill the bounds.
@interface FHVideoPlayerView : UIView
@end
@interface FHVideoPlayerView
+ (Class)layerClass
{
return [AVPlayerLayer class];
}
- (void)setAspectMode:(FHVideoPlayerAspectMode)aspectMode animated:(BOOL)animated
{
FHVideoPlayerAspectMode current = [self aspectMode];
FHVideoPlayerAspectMode final = aspectMode;
NSString *fromValue;
NSString *toValue;
AVPlayerLayer *layer = (AVPlayerLayer *)[self layer];
switch (current) {
case FHVideoPlayerAspectFill:
fromValue = AVLayerVideoGravityResizeAspectFill;
break;
case FHVideoPlayerAspectFit:
fromValue = AVLayerVideoGravityResizeAspect;
break;
default:
break;
}
switch (final) {
case FHVideoPlayerAspectFill:
toValue = AVLayerVideoGravityResizeAspectFill;
break;
case FHVideoPlayerAspectFit:
toValue = AVLayerVideoGravityResizeAspect;
break;
default:
break;
}
if (toValue != fromValue) {
if (animated == YES) {
// Manually added CABasicAnimation based on the understanding the implicit animations are disabled for CALayers that back a UIView
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"videoGravity"];
[layer addAnimation:animation forKey:@"animateVideoGravity"];
[CATransaction begin];
[CATransaction setAnimationDuration:0.333];
}
[layer setVideoGravity:toValue];
if (animated == YES) {
[CATransaction commit];
}
}
}
This works just fine when I try and animate a numeric property such as opacity. But, you'll notice from the class reference, AVPlayerLayer's videoGravity property is an NSString. The class reference does points out that it is animatable.
So my question is: How!?
I believe this is probably related somehow to CALayer's content property and possibly contentsGravity.