动画AVPlayerLayer videoGravity属性 [英] Animate AVPlayerLayer videoGravity property
问题描述
我正在尝试复制Apple在视频播放中的行为,允许用户拉伸视频图像以填充边界。
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];
}
}
}
我工作正常尝试为不透明度等数字属性设置动画。但是,你会从类引用中注意到,AVPlayerLayer的videoGravity属性是一个NSString。类引用确实指出它是可动画的。
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相信这可能与CALayer的内容属性以及可能的contentsGravity有关。
I believe this is probably related somehow to CALayer's content property and possibly contentsGravity.
推荐答案
正如voromax所指出的,这是iOS中的一个错误5.0。我在iOS 5.1中反向设计了 - [AVPlayerLayer setVideoGravity:]
实现,以便了解动画应该如何工作。以下是如何解决这个错误,并在iOS 5.0上有一个很好的动画。
As voromax pointed out, this is a bug in iOS 5.0. I reverse engineered -[AVPlayerLayer setVideoGravity:]
implementation in iOS 5.1 in order to understand how the animation was supposed to work. Here is how to workaround the bug and have a nice animation on iOS 5.0.
@implementation VideoPlayerView
+ (Class) layerClass
{
return [AVPlayerLayer class];
}
- (AVPlayerLayer *) playerLayer
{
return (AVPlayerLayer *)[self layer];
}
- (NSString *) videoGravity
{
return self.playerLayer.videoGravity;
}
- (void) setVideoGravity:(NSString *)videoGravity
{
self.playerLayer.videoGravity = videoGravity;
// Workaround a bug in iOS 5.0
float avFoundationVersion = [[[NSBundle bundleForClass:[AVPlayerLayer class]] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] floatValue];
if (avFoundationVersion < 292.24f)
{
@try
{
NSString *contentLayerKeyPath = [NSString stringWithFormat:@"%1$@%2$@.%3$@%2$@", @"player", [@"layer" capitalizedString], @"content"]; // playerLayer.contentLayer
CALayer *contentLayer = [self.playerLayer valueForKeyPath:contentLayerKeyPath];
if ([contentLayer isKindOfClass:[CALayer class]])
[contentLayer addAnimation:[CABasicAnimation animation] forKey:@"sublayerTransform"];
}
@catch (NSException *exception)
{
}
self.bounds = self.bounds;
}
}
@end
这篇关于动画AVPlayerLayer videoGravity属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!