AVPlayerLayer не привязан к фрейму UIView
Я пытаюсь добавить AVPlayerLayer в UIView
self.player = AVPlayer(URL: NSURL(fileURLWithPath: path!))
self.playerLayer = AVPlayerLayer(player: player);
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.playerLayer.frame = ctrVideo.bounds;
self.ctrVideo.layer.addSublayer(playerLayer);
player.play();
Это контейнер видео (синего цвета):
Я не могу понять, почему видео не привязано к UIVIew координатам. Если я ограничу это в супервизии контроллера, это нормально.
4 ответа
Решение
Подслой не будет автоматически изменять размер при смене фрейма представления, вы должны сделать это вручную. Вы можете создать подкласс UIView, чтобы упростить его.
class VideoContainerView: UIView {
var playerLayer: CALayer?
override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
playerLayer?.frame = self.bounds
}
}
И тогда в вашем коде:
self.player = AVPlayer(URL: NSURL(fileURLWithPath: path!))
self.playerLayer = AVPlayerLayer(player: player);
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.playerLayer.frame = ctrVideo.bounds;
self.ctrVideo.layer.addSublayer(playerLayer);
self.ctrVideo.playerLayer = playerLayer;
player.play();
Просто убедитесь, что вы изменили этот класс вашего "ctrVideo" с UIView на VideoContainerView.
Вот потрясающий ответ @almas в Swift 4
class VideoContainerView: UIView {
var playerLayer: CALayer?
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
playerLayer?.frame = self.bounds
}
}
Я добавил AVPlayerLayer в событие viewDidLoad... До того, как применяются ограничения.
Вот AVPlayerLayer
поддерживаемое представление, которое пытается сохранить свое соотношение сторон.
PlayerView.h:
@interface PlayerView : UIView
@property (strong, nonatomic) AVPlayerLayer *layer;
@end
PlayerView.m:
@interface PlayerView ()
@property (strong, nonatomic) NSLayoutConstraint *aspectConstraint;
@end
@implementation PlayerView
@dynamic layer;
+ (Class)layerClass {
return [AVPlayerLayer class];
}
- (instancetype)init {
self = [super init];
if (self) {
self.userInteractionEnabled = NO;
[self addObserver:self forKeyPath:@"layer.videoRect" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void)dealloc {
[self removeObserver:self forKeyPath:@"layer.videoRect"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"layer.videoRect"]) {
CGSize size = [change[NSKeyValueChangeNewKey] CGRectValue].size;
if (change[NSKeyValueChangeNewKey] && size.width && size.height) {
self.aspectConstraint.active = NO;
self.aspectConstraint = [self.widthAnchor constraintEqualToAnchor:self.heightAnchor multiplier:size.width / size.height];
self.aspectConstraint.priority = UILayoutPriorityDefaultHigh;
self.aspectConstraint.active = YES;
}
else {
self.aspectConstraint.active = NO;
}
}
}
@end