视图内的AVPlayer图层在UIView帧更改时不resize

我有一个UIView包含一个AVPlayer来显示video。 改变方向时,我需要改变video的大小和位置。

我对调整层次不是很有经验,所以我在调整video时遇到了问题。

我开始创buildAVPlayer并将其播放器添加到我的videoHolderView图层:

 NSURL *videoURL = [NSURL fileURLWithPath:videoPath]; self.avPlayer = [AVPlayer playerWithURL:videoURL]; AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer]; playerLayer.frame = videoHolderView.bounds; playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; playerLayer.needsDisplayOnBoundsChange = YES; [videoHolderView.layer addSublayer:playerLayer]; videoHolderView.layer.needsDisplayOnBoundsChange = YES; 

然后,稍后,我更改videoHolderView框架的大小和位置:

 [videoHolderView setFrame:CGRectMake(0, 0, 768, 502)]; 

在这一点上,我需要avPlayer调整到这些相同的尺寸。 这不会自动发生 – avPlayer停留在videoHolderView内的小尺寸。

如果有人可以帮忙,我真的很感激任何意见。

多谢你们。

  playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFit; 

其实你不应该把AVPlayer的图层添加为子图层。 而不是你应该使用下面的方法,在你想要显示AVPlayer的视图的子类。

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

并使用下面的行添加(设置)播放器层。

 [(AVPlayerLayer *)self.layer setPlayer:self.avPlayer]; 

希望能帮助到你;-)

最后,我通过将AVPlayerLayer重新添加到UIView中解决了这个问题。 我不知道为什么改变框架删除图层,但它确实。 这是最终的解决scheme:

 //amend the frame of the view [videoHolderView setFrame:CGRectMake(0, 0, 768, 502)]; //reset the layer's frame, and re-add it to the view AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer]; playerLayer.frame = videoHolderView.bounds; [videoHolderView.layer addSublayer:playerLayer]; 

将@ Suran的解决scheme转换成Swift 3:

首先,创build一个inheritanceUIView的类,只覆盖1个variables:

 import UIKit import AVFoundation class AVPlayerView: UIView { override class var layerClass: AnyClass { return AVPlayerLayer.self } } 

然后使用界面生成器添加一个简单的UIView,并将其类更改为刚创build的类:AVPlayerView

将常规UIView的类更改为AVPlayerView

然后,为这个观点制定一个出路。 称之为avPlayerView

 @IBOutlet weak var avPlayerView: AVPlayerView! 

现在,您可以在viewcontroller中使用该视图并像这样访问其avlayer:

 let avPlayer = AVPlayer(url: video) let castedLayer = avPlayerView.layer as! AVPlayerLayer castedLayer.player = avPlayer avPlayer.play() 

现在,图层将像普通图层一样遵循约束条件。 无需手动更改边界或大小。

您可以通过覆盖-layoutSubviews方法来更改图层的框架:

 - (void)layoutSubviews { [super layoutSubviews]; self.playerLayer.frame = self.bounds; } 

第一步:在UIVIew.h中检查UIView的autoresizing属性

@属性(非primefaces)UIViewAutoresizing autoresizingMask; //简单的resize 默认是UIViewAutoresizingNone

这个属性logging了IB中的“spring和struts”控件,虽然它会带你进行一些实验来获得你想要的结果。

Dunc的回答对我不起作用。 我发现了一个更简单的解决scheme:我只需要在UIView中更改AVPlayerLayer的框架就可以了:

 avPlayerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 

在这个博客中说,一个视图的框架也影响到它的层。

当你改变一个视图的框架时,它只是改变图层的框架。

对于这种情况,这是不正确的。

要访问playerLayer ,您需要循环访问videoHolderView.layer.sublayers并更改每个。

这就是我在Swift 2.2中所做的

 if let sublayers = videoHolderView.layer.sublayers{ for layer in sublayers where layer is AVPlayerLayer{ layer.frame.size = ... // change size of the layer here } } 

发现Marco Santarossa的一篇很棒的文章,展示了多种修复方法。 https://marcosantadev.com/calayer-auto-layout-swift/

我用他的第一个build议来重置viewDidLayoutSubViews()事件期间的图层框架。

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() playerLayer.frame = view.layer.bounds } 

任何人searchXamarin版本,我正在寻找

不要将AVPlayerLayer添加为子图层,而是将图层设置为Avplayer图层

 [Export("layerClass")] public static Class LayerClass() { return new Class(typeof(AVPlayerLayer)); } 

以下行设置图层

 (this.Layer as AVPlayerLayer).Player = _player; // Acplayer 

我有这个问题在Swift 2.3,我解决了写一个适当的PlayerView类,并将其设置为子视图:

 import UIKit import AVKit import AVFoundation class PlayerPreviewView: UIView { override class func layerClass() -> AnyClass { return AVPlayerLayer.self } var player: AVPlayer? { get { return playerLayer.player } set { playerLayer.player = newValue } } var playerLayer: AVPlayerLayer { return layer as! AVPlayerLayer } override init(frame: CGRect) { super.init(frame: frame) playerLayer.videoGravity = AVLayerVideoGravityResize } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) playerLayer.videoGravity = AVLayerVideoGravityResize } } 

在呈现ViewController中:

 private func play(asset asset: AVURLAsset){ let playerItem = AVPlayerItem(asset: asset) player = AVPlayer(playerItem: playerItem) player?.actionAtItemEnd = .None player?.muted = true playerPreviewView = PlayerPreviewView(frame: CGRectZero) view.addSubview(playerPreviewView) playerPreviewView.player = player playerPreviewView.translatesAutoresizingMaskIntoConstraints = false view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": playerPreviewView])) view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": playerPreviewView])) player?.play() NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SplashScreenViewController.videoDidFinish), name: AVPlayerItemDidPlayToEndTimeNotification, object: nil) }