You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI设置AVPlayerViewController为全屏背景时上层视图忽略安全区问题

问题原因

AVPlayerViewController 是 UIKit 体系的视图控制器,默认会向父级 SwiftUI 视图传递全屏布局偏好,当它作为 background 修饰符的内容时,自身的安全区忽略配置会意外向上传导,最终导致上层内容视图被拉伸到安全区外。普通 SwiftUI 视图(如 Color)作为背景时不会触发这个传导逻辑,因此不会出现异常。

解决方案1:使用 ZStack 层级拆分(最推荐)

不要将视频视图放在 background 修饰符中,改用 ZStack 独立拆分背景层和内容层,各自控制安全区策略即可:

var body: some View {
    ZStack {
        // 背景层:视频全屏展示,忽略所有安全区
        VideoPlayerController(videoURL: videoURL, isPlaying: $isPlaying)
            .edgesIgnoringSafeArea(.all)
        
        // 内容层:默认遵循安全区规则,不会被拉伸
        VStack(spacing: 0) {
            HStack {
                Text("Some text")
                Spacer()
            }
            Spacer()
        }
        .padding(16)
        .foregroundColor(.white)
    }
}

解决方案2:调整 VideoPlayerController 实现

如果你需要保留 background 的写法,可以修改封装的 VideoPlayerController,阻断布局偏好的向上传导:

struct VideoPlayerController: UIViewControllerRepresentable {
    typealias UIViewControllerType = AVPlayerViewController
    
    var videoURL: URL
    @Binding var isPlaying: Bool
    let showPlaybackControls = false
    
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let player = AVPlayer(url: videoURL)
        let playerController = AVPlayerViewController()
        
        playerController.player = player
        playerController.showsPlaybackControls = showPlaybackControls
        // 配置视图控制器的布局扩展规则
        playerController.edgesForExtendedLayout = .all
        playerController.extendedLayoutIncludesOpaqueBars = true
        return playerController
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
        if isPlaying {
            uiViewController.player?.play()
        } else {
            uiViewController.player?.pause()
        }
    }
    
    // 明确指定尺寸匹配父视图提议,阻断异常布局传导
    func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: AVPlayerViewController, context: Context) -> CGSize? {
        return proposal.replacingUnspecifiedDimensions()
    }
}

修改完成后原有代码无需改动,内容视图即可正常遵循安全区规则。

内容的提问来源于stack exchange,提问作者AlexKost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:57:02