SwiftUI中Scroll View内视频播放器的自适应尺寸问题
解决ScrollView中SwiftUI视频播放器缩放异常问题
核心问题分析
AVPlayerViewController作为UIKit视图嵌入SwiftUI时,在ScrollView这类滚动容器内会丢失布局约束,加上原代码中硬编码的宽度计算和未明确的比例约束,导致尺寸缩放异常。以下是针对性的修复方案:
修复步骤及代码修改
1. 给视频播放器添加比例约束
在HustleVideoPlayer中,需要明确视频的宽高比,让SwiftUI能正确计算布局尺寸。支持固定比例(如16:9)或动态获取视频原始比例两种方式。
修改后的HustleVideoPlayer:
struct HustleVideoPlayer: View { let url: URL @State var player = AVPlayer() @State private var videoAspectRatio: CGFloat = 16/9 // 默认16:9,可替换为动态获取 var body: some View { ZStack { VideoPlayer(player: $player) } .aspectRatio(videoAspectRatio, contentMode: .fit) .onAppear { // 初始化播放器 player = AVPlayer(url: url) player.play() // 可选:动态获取视频原始宽高比 let asset = AVAsset(url: url) let videoTracks = asset.tracks(withMediaType: .video) if let track = videoTracks.first { let naturalSize = track.naturalSize.applying(track.preferredTransform) videoAspectRatio = abs(naturalSize.width / naturalSize.height) } } } }
2. 调整ScrollView内的HStack布局
去掉硬编码的宽度计算,让播放器自动填充可用水平空间,同时给其他元素设置明确尺寸保证布局稳定:
修改后的UploadHustleCamera:
struct UploadHustleCamera: View { let url: URL var body: some View { ScrollView { HStack(spacing: 12) { RoundedRectangle(cornerRadius: 5) .frame(width: 40, height: 40) .foregroundColor(.gray) Text("hello") Spacer() HustleVideoPlayer(url: url) .frame(maxWidth: .infinity) // 占满剩余水平空间 } .padding() } } }
3. 统一视频填充模式避免冲突
确保VideoPlayer中的videoGravity和SwiftUI的contentMode匹配,防止布局逻辑冲突:
修改后的VideoPlayer:
struct VideoPlayer : UIViewControllerRepresentable { @Binding var player : AVPlayer func makeUIViewController(context: Context) -> AVPlayerViewController { let controller = AVPlayerViewController() controller.player = player controller.showsPlaybackControls = false // 和SwiftUI的contentMode: .fit对应,若用.fill则改为.resizeAspectFill controller.videoGravity = .resizeAspect return controller } func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) { } }
关键说明
- ScrollView内的布局需要明确约束优先级,
frame(maxWidth: .infinity)可让播放器自动填充剩余空间。 - AVPlayerViewController本身不会自动适配SwiftUI布局,必须通过
aspectRatio给它明确的宽高比约束。 - 动态获取视频比例能让播放器贴合视频原始尺寸,固定比例场景可直接写死数值简化逻辑。
内容的提问来源于stack exchange,提问作者Ahmed Zaidan
相关产品推荐
相关产品推荐

