如何让AVPlayerLayer铺满UIView并实现视频循环播放?
解决AVPlayerLayer无法铺满UIView的问题
你的代码仅设置了AVPlayerLayer的初始尺寸,未处理视图布局变化的场景,且尺寸设置方式不够稳妥,导致无法始终铺满videoView。可以通过以下两步调整:
1. 保存AVPlayerLayer引用并正确设置初始尺寸
先在类中添加AVPlayerLayer类型的属性,方便后续更新尺寸;然后直接将图层的frame设为videoView的bounds,替代原分开设置bounds和position的方式:
// 在类顶部添加属性 var player: AVPlayer? var playerLayer: AVPlayerLayer? // 新增该属性 func playVideo(videoString: String) { guard let videoURL = URL(string: videoString) else { return } self.player = AVPlayer(url: videoURL) self.player?.isMuted = true self.player?.actionAtItemEnd = .none self.playerLayer = AVPlayerLayer(player: player) self.playerLayer?.videoGravity = .resizeAspectFill self.playerLayer?.frame = self.videoView.bounds // 直接绑定videoView的bounds self.videoView.layer.addSublayer(playerLayer!) self.player?.play() NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd), name: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem) } @objc func playerItemDidReachEnd(notification: NSNotification) { self.player?.seek(to: .zero) self.player?.play() }
2. 监听视图布局变化,动态更新图层尺寸
当videoView尺寸变化(比如屏幕旋转、父视图布局更新)时,同步更新playerLayer的尺寸。如果是在ViewController中,重写viewDidLayoutSubviews方法:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 每次布局更新时,让playerLayer的frame与videoView的bounds保持一致 self.playerLayer?.frame = self.videoView.bounds }
如果videoView是自定义UIView,可在自定义类中重写layoutSubviews:
class CustomVideoView: UIView { override func layoutSubviews() { super.layoutSubviews() // 找到子图层中的AVPlayerLayer并更新frame if let playerLayer = layer.sublayers?.first(where: { $0 is AVPlayerLayer }) as? AVPlayerLayer { playerLayer.frame = bounds } } }
调整后,AVPlayerLayer就能始终铺满整个videoView。其中resizeAspectFill会让视频填满视图,超出部分会被裁剪;若需视频完整显示不裁剪,可改用.resizeAspect。
内容的提问来源于stack exchange,提问作者Telha Wasim
相关产品推荐
相关产品推荐

