SwiftUI实现视频垂直填满iPhone屏幕并保持原比例(左右裁切)
SwiftUI实现横屏视频竖屏垂直填满且不拉伸的方案
要实现横屏视频在竖屏iPhone上垂直填满屏幕、保持比例不拉伸,裁切左右超出部分,可通过自定义视频播放器视图来实现,具体方案如下:
核心思路
利用AVPlayerLayer的videoGravity属性设置为.resizeAspectFill,该模式会保持视频原有比例,同时让视频填满容器,超出容器的部分自动裁切。在SwiftUI中我们通过UIViewRepresentable封装自定义播放器视图来对接这个原生属性。
完整代码实现
import SwiftUI import AVKit // 自定义支持重力模式的视频播放器 struct CustomVideoPlayer: UIViewRepresentable { let player: AVPlayer let videoGravity: AVLayerVideoGravity func makeUIView(context: Context) -> UIView { let view = UIView(frame: .zero) let playerLayer = AVPlayerLayer(player: player) playerLayer.videoGravity = videoGravity playerLayer.frame = view.bounds view.layer.addSublayer(playerLayer) context.coordinator.playerLayer = playerLayer return view } func updateUIView(_ uiView: UIView, context: Context) { context.coordinator.playerLayer?.frame = uiView.bounds } func makeCoordinator() -> Coordinator { Coordinator() } class Coordinator { var playerLayer: AVPlayerLayer? } } struct SignInView: View { private let player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "DL_preview", ofType: "mp4")!)) var body: some View { ZStack { CustomVideoPlayer(player: player, videoGravity: .resizeAspectFill) .ignoresSafeArea() .onAppear { player.isMuted = true player.play() // 配置循环播放 NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: .main) { _ in player.seek(to: .zero) player.play() } } .onDisappear { NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem) } // 叠加的界面元素区域 VStack { // 在这里添加你的登录相关UI组件 Text("登录") .font(.largeTitle) .foregroundColor(.white) // ...其他UI元素 } } } }
关键细节说明
.resizeAspectFill:这是实现需求的核心设置,确保视频按比例缩放后垂直方向填满屏幕,左右超出部分被裁切,完全避免拉伸变形。ignoresSafeArea():让视频延伸覆盖屏幕的刘海、底部安全区域,实现真正的全屏填充效果。- 循环播放:通过监听播放结束通知,实现视频播放完毕后自动重置并重新播放,适配背景视频的场景需求。
内容的提问来源于stack exchange,提问作者weekendwarrior
相关产品推荐
相关产品推荐

