关于iPhone:AVPlayerLayer不会绑定到UIView框架

AVPlayerLayer not bounds to UIView frame

我正在尝试将AVPlayerLayer添加到UIView

1
2
3
4
5
6
    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();

这是视频的容器(蓝色):

This is the view:

限制条件:
Constraints:

最后结果:
enter image description here

我不知道为什么视频不绑定到UIVIew坐标。 如果我将其绑定到控制器的超级视图中,就可以了。


当视图的框架更改时,子图层不会自动调整大小,您必须手动进行调整。 您可以将UIView子类化以使其变得更容易。

1
2
3
4
5
6
7
class VideoContainerView: UIView {
  var playerLayer: CALayer?
  override func layoutSublayersOfLayer(layer: CALayer) {
    super.layoutSublayersOfLayer(layer)
    playerLayer?.frame = self.bounds
  }
}

然后在您的代码中:

1
2
3
4
5
6
7
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。


我在viewDidLoad事件中添加了AVPlayerLayer ...在应用约束之前。


这是Swift 4中@almas的出色答案

1
2
3
4
5
6
7
8
class VideoContainerView: UIView {    
    var playerLayer: CALayer?

    override func layoutSublayers(of layer: CALayer) {
        super.layoutSublayers(of: layer)
        playerLayer?.frame = self.bounds
    }
}

这是AVPlayerLayer支持的视图,试图保持其宽高比。

PlayerView.h:

1
2
3
4
5
@interface PlayerView : UIView

@property (strong, nonatomic) AVPlayerLayer *layer;

@end

PlayerView.m:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@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