在较大的手机上,我的 AVPlayer(显示视频)不会按预期占用整个视图宽度。它在我的 iPhone 15 pro 上运行完美,但模拟器中的 iPhone 16 plus 出现问题。我尝试了很多方法来修复它,例如对视频设置限制,但似乎没有任何效果。我在下面附上了屏幕截图和我的代码。提前感谢您的帮助!
@IBOutlet weak var cover: UIView!
private var playerLayer: AVPlayerLayer?
private func setupVideoCover() {[
player = AVPlayer(url: videoURL)
player?.isMuted = true
player?.actionAtItemEnd = .none
playerLayer = AVPlayerLayer(player: player)
if let playerLayer = playerLayer {
cover.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
cover.layer.addSublayer(playerLayer)
}
NotificationCenter.default.addObserver(
self,
selector: #selector(restartVideoFromBeginning),
name: .AVPlayerItemDidPlayToEndTime,
object: player?.currentItem
)
player?.play()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
playerLayer?.videoGravity = .resizeAspectFill
playerLayer?.frame = cover.bounds.centered(in: cover.bounds)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupVideoCover()
}
正如 Apple 文档中关于
viewDidLayoutSubviews
的解释:
调用此方法并不表明各个布局 视图的子视图已被调整。每个子视图负责 用于调整自己的布局。
因此,当
viewDidLayoutSubviews
被调用时,您的 cover
在屏幕上布局时尚未获得其框架。要根据 playerLayer
的边界设置 cover
的框架,正确的方法是使用 layoutSubviews
的方法 UIView
:
class ViewController: UIViewController {
@IBOutlet weak var cover: CoverView! // <- change to CoverView
...
}
class CoverView: UIView {
private var playerLayer: AVPlayerLayer?
override func layoutSubviews() {
super.layoutSubviews()
playerLayer?.videoGravity = .resizeAspectFill
//set frame here
playerLayer?.frame = cover.bounds.centered(in: cover.bounds)
}
}
就您而言,您的代码在 iPhone 15 pro 上运行良好,因为您的 xib 文件可能设置为 iPhone 15 pro,因此封面的框架最初基于 xib 文件