如何在SwiftUI中为AVPlayerViewController添加下滑关闭功能?
解决SwiftUI中AVPlayerViewController下滑关闭问题
要实现下滑关闭功能,核心是不要直接将AVPlayerViewController嵌入SwiftUI视图层级,而是通过SwiftUI的sheet或fullScreenCover来模态呈现它——系统会自动为模态视图添加下滑关闭手势。同时优化自动播放的实现,避免全局扩展影响其他AVPlayerViewController实例。
修改后的完整代码
import SwiftUI import AVKit struct AVPlayerControllerView: UIViewControllerRepresentable { let player: AVPlayer let onViewAppear: (AVPlayerViewController) -> Void func makeUIViewController(context: Context) -> AVPlayerViewController { let vc = AVPlayerViewController() vc.player = player vc.delegate = context.coordinator return vc } func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, AVPlayerViewControllerDelegate { let parent: AVPlayerControllerView init(_ parent: AVPlayerControllerView) { self.parent = parent super.init() } func playerViewControllerDidAppear(_ playerViewController: AVPlayerViewController) { parent.onViewAppear(playerViewController) } } } // 使用示例 struct PlayerDemoView: View { @State private var isPlayerPresented = false private let player: AVPlayer = { guard let url = URL(string: "https://example.com/your-video.mp4") else { return AVPlayer() } return AVPlayer(url: url) }() var body: some View { Button("播放视频") { isPlayerPresented = true } .sheet(isPresented: $isPlayerPresented) { AVPlayerControllerView(player: player) { vc in vc.player?.play() } } } }
关键说明
- 模态呈现:通过
sheet(半屏)或fullScreenCover(全屏)展示播放器,系统原生支持下滑关闭手势,无需额外实现代理或手势识别逻辑。 - 优化自动播放:通过
Coordinator绑定播放器代理,配合自定义回调触发自动播放,避免全局扩展AVPlayerViewController带来的副作用。 - 自定义嵌入场景的备选方案:如果必须将播放器嵌入现有视图而非模态呈现,需手动添加
UIPanGestureRecognizer,监听手势偏移量动态修改视图位置,同时自行处理视图的 Dismiss 逻辑,但这种方式复杂度远高于系统模态方案。
内容的提问来源于stack exchange,提问作者Aleš Kocur
相关产品推荐
相关产品推荐

