AVPlayerLayer可以动画地改变其frame属性。

17
无论何时我改变AVPlayerLayer的框架,视频不会立即调整大小,而是动画效果地调整到新的大小。
例如:我将框架从(0, 0, 100, 100)更改为(0, 0, 400, 400),视图的框架立即更改,但视频的大小会以动画方式调整到新的大小。
有人遇到过这个问题吗?如果是,有人知道如何禁用默认的动画吗?
谢谢!

1
有趣的是,我遇到了相反的问题:我无法让AVPlayerLayer上的动画工作! - Nicolas Miari
7个回答

25

你可以尝试禁用隐式动作并使用零长度的动画:

CALayer *videolayer = <# AVPlayerLayer #>
[CATransaction begin];
[CATransaction setAnimationDuration:0];
[CATransaction setDisableActions:YES];
CGRect rect = videolayer.bounds;
rect.size.width /= 3;
rect.size.height /= 3;
videolayer.bounds = rect; 
[CATransaction commit];

是的,看起来工作正常。干杯。提醒其他人:这需要QuartzCore.framework来使用CATransaction。 - Wex

8
这是我使用的内容:
AVPlayerLayer * playerLayer = <# AVPlayerLayer #>;
playerLayer.frame = <# CGRect #>;
[playerLayer removeAllAnimations];

希望这能有所帮助。我不知道它是否符合最佳实践,但对我很有效。 似乎每当使用“.frame”或“setFrame”时,都会向图层添加动画。


2
尝试在Swift中实现,但是将playerLayer.removeAllAnimations()放错了位置。你需要在每次改变帧之后直接调用它,而不是在创建图层时调用。 - Thyselius

4

处理这个问题最简单、最干净的方式是创建一个UIView子类,将AVPlayerLayer作为其layerClass。这样做,AVPlayerLayer就会像普通的UIView层一样运行。您可以改变视图的框架而不是图层,没有任何隐式动画会发生。

AVPlayerLayerView.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AVPlayerLayerView : UIView

@property (nonatomic, readonly) AVPlayerLayer *playerLayer;

@end

AVPlayerLayerView.m

#import "AVPlayerLayerView.h"

@implementation AVPlayerLayerView

+ (Class)layerClass {
    return [AVPlayerLayer class];
}

- (AVPlayerLayer *)playerLayer {
    return (AVPlayerLayer *)self.layer;
}

@end

现在您可以这样做:
playerLayerView.frame = CGRectMake(0, 0, 400, 400);

要将AVPlayerLayer与AVPlayer关联,只需执行以下操作:
playerLayerView.playerLayer.player = player;

2

你使用吗?:

- (void)setPlayer:(AVPlayer *)player {
    [(AVPlayerLayer *)[self layer] setPlayer:player];
    [(AVPlayerLayer *)[self layer] setVideoGravity:AVLayerVideoGravityResize];
}

2

在改变 playerLayerframe 后,我在 Swift 中做的事情如下:

playerLayer.removeAllAnimations()

1

我通过以下方式在Swift 4中使其工作:

    var videoLayer = AVPlayerLayer()
    CATransaction.begin()
    CATransaction.setAnimationDuration(0)
    CATransaction.setDisableActions(true)
    var rect = videoLayer.bounds
    rect.size.width /= 3
    rect.size.height /= 3
    videoLayer.bounds = rect
    CATransaction.commit()

0

在某些情况下,可能会有所帮助:

在包含播放器层的视图中添加自定义的“setFrame:”设置器

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];

    self.playerLayer.frame = CGRectMake(0.0f, 0.0f, frame.size.width, frame.size.height);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接