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

SwiftUI iPad自定义视频播放器:仅保留全屏按钮隐藏其余控件

自定义SwiftUI iPad视频播放器:仅保留全屏按钮

要实现隐藏原生所有控件、仅保留自定义全屏按钮的视频播放器,我们可以通过隐藏原生播放控件+添加自定义全屏按钮+实现全屏切换逻辑来完成,以下是完整的实现方案:

步骤1:修改自定义视频播放器(支持全屏状态绑定)

给CustomVideoPlayer添加状态绑定,实现SwiftUI与UIKit的状态同步,同时优化通知监听的生命周期避免内存泄漏:

import SwiftUI
import AVKit

struct CustomVideoPlayer: UIViewControllerRepresentable {
    var player: AVPlayer
    @Binding var isFullScreen: Bool
    private let playerObserver = PlayerObserver()
    
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let controller = AVPlayerViewController()
        controller.player = player
        controller.showsPlaybackControls = false
        controller.videoGravity = .resizeAspectFill
        
        // 绑定全屏状态回调
        context.coordinator.controller = controller
        context.coordinator.isFullScreen = $isFullScreen
        
        // 设置循环播放
        playerObserver.startObserving(player: player)
        
        return controller
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
        // 根据绑定状态切换全屏
        if isFullScreen {
            uiViewController.enterFullScreen(animated: true)
        } else {
            uiViewController.exitFullScreen(animated: true)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    // 协调UIKit与SwiftUI的状态交互
    class Coordinator: NSObject {
        weak var controller: AVPlayerViewController?
        var isFullScreen: Binding<Bool>?
        
        @objc func handleFullScreenChange(_ notification: Notification) {
            guard let controller = controller, let isFullScreen = isFullScreen else { return }
            DispatchQueue.main.async {
                isFullScreen.wrappedValue = controller.isFullScreen
            }
        }
    }
    
    // 封装循环播放的通知监听,避免内存泄漏
    class PlayerObserver: NSObject {
        private var observer: NSObjectProtocol?
        
        func startObserving(player: AVPlayer) {
            observer = NotificationCenter.default.addObserver(
                forName: .AVPlayerItemDidPlayToEndTime,
                object: player.currentItem,
                queue: .main
            ) { [weak self] _ in
                guard let self = self else { return }
                player.seek(to: .zero)
                player.play()
            }
        }
        
        deinit {
            if let observer = observer {
                NotificationCenter.default.removeObserver(observer)
            }
        }
    }
}

步骤2:在ContentView中添加自定义全屏按钮

通过ZStack将自定义全屏按钮叠加在视频播放器上层,点击时切换全屏状态:

import SwiftUI
import AVKit

struct ContentView: View {
    private let player1 = AVPlayer(url: URL(string: "urlPlaceholder")!)
    @State private var isFullScreen = false
    
    var body: some View {
        ZStack {
            CustomVideoPlayer(player: player1, isFullScreen: $isFullScreen)
                .onAppear {
                    player1.play()
                }
            
            // 自定义全屏按钮,固定在右下角
            Button(action: {
                isFullScreen.toggle()
            }) {
                Image(systemName: isFullScreen ? "arrow.down.right.and.arrow.up.left" : "arrow.up.left.and.arrow.down.right")
                    .foregroundColor(.white)
                    .padding()
                    .background(Color.black.opacity(0.5))
                    .cornerRadius(8)
            }
            .padding(.bottom, 20)
            .padding(.trailing, 20)
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing)
            .opacity(isFullScreen ? 0 : 1) // 全屏时隐藏按钮,退出时显示
        }
        .edgesIgnoringSafeArea(isFullScreen ? .all : .none)
    }
}

关键说明

  • 状态双向绑定:通过@Binding实现SwiftUI的isFullScreen状态与UIKit播放器的全屏状态同步,确保交互一致性。
  • 生命周期管理:将循环播放的通知监听封装到独立类中,在对象销毁时自动移除监听,避免内存泄漏。
  • 系统级全屏切换:利用AVPlayerViewController的原生全屏方法实现系统级的全屏体验,无需手动调整视图布局。
  • 自定义按钮交互:根据全屏状态切换按钮图标,全屏时自动隐藏按钮,符合用户操作习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:55:20