AVPlayerLayer оживляет изменения кадров
Всякий раз, когда я меняю кадр моего AVPlayerLayer, видео не изменяется сразу, а анимируется до нового размера.
Например: я меняю фрейм с (0, 0, 100, 100) на (0, 0, 400, 400), рамка просмотра сразу изменяется, но размер видео анимируется до нового размера.
Кто-нибудь столкнулся с этой проблемой? И если да, то кто-нибудь знает способ отключить анимацию по умолчанию?
Спасибо!
Ответы
Ответ 1
Вы можете попробовать отключить неявные действия и использовать анимацию нулевой длины:
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];
Ответ 2
Самый простой и чистый способ справиться с этим - создать подкласс 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;
Ответ 3
Это то, что я использовал:
AVPlayerLayer * playerLayer = <# AVPlayerLayer #>;
playerLayer.frame = <# CGRect #>;
[playerLayer removeAllAnimations];
Надеюсь, это поможет. Я не знаю, являются ли его лучшие практики, но это работает для меня.
Кажется, что всякий раз, когда используется ".frame" или "setFrame", он добавляет анимацию к слою.
Ответ 4
Вы используете?:
- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
[(AVPlayerLayer *)[self layer] setVideoGravity:AVLayerVideoGravityResize];
}
Ответ 5
Вот что я делаю в Swift сразу после изменения playerLayer
frame
:
playerLayer.removeAllAnimations()
Ответ 6
Вероятно, это поможет в некоторых случаях:
добавление настраиваемого установщика setFrame: ', содержащего слой игрока
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
self.playerLayer.frame = CGRectMake(0.0f, 0.0f, frame.size.width, frame.size.height);
}
Ответ 7
Я получил это, работая в 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()