I've a problem with SwiftUI and AVPlayer. When i rotate the device in landscape mode, the player go in fullscreen mode, but when I rotate in portrait it not exit.
The struct for AVPlayer:

import SwiftUI
import AVKit

struct AVPlayerControllerRepresentable: UIViewControllerRepresentable {
    @Binding var showFullScreen: Bool
    @Binding var player: AVPlayer
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<AVPlayerControllerRepresentable>) -> AVPlayerViewController {
        print("makeUIViewController->",showFullScreen)
        let controller  = AVPlayerViewController()
        controller.player = player
        controller.showsPlaybackControls = false;
        chooseScreenType(controller)
        return controller
    }
    
    func updateUIViewController(_  uiViewController: AVPlayerViewController , context: UIViewControllerRepresentableContext<AVPlayerControllerRepresentable>) {
        print("updateUIViewController->",showFullScreen)
        chooseScreenType(uiViewController)
    }
    
    private func chooseScreenType(_ controller: AVPlayerViewController) {
        print("chooseScreenType", self.showFullScreen)
        self.showFullScreen ? controller.enterFullScreen(animated: true) : controller.exitFullScreen(animated: true)
    }
    
}

extension AVPlayerViewController {
    func enterFullScreen(animated: Bool) {
        print("Enter full screen")
        perform(NSSelectorFromString("enterFullScreenAnimated:completionHandler:"), with: animated, with: nil)
    }
    
    func exitFullScreen(animated: Bool) {
        print("Exit full screen")
        perform(NSSelectorFromString("exitFullScreenAnimated:completionHandler:"), with: animated, with: nil)
    }
}

这是我的观点:

 VStack{
                       

         AVPlayerControllerRepresentable(showFullScreen: $fullScreen, player: $player)
                                    .ignoresSafeArea()
                                    .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                                        DispatchQueue.main.async {
                                            print("change rotation->",UIDevice.current.orientation.rawValue)
                                            if UIDevice.current.orientation.isLandscape {
                                                print("landscape")
                                                self.fullScreen = true
                                            } else {
                                                print("portrait")
                                                self.fullScreen = false
                                            }
                                        }
                                    }
                                    .frame(width: 290, height: 220)
                                    .overlay {
                                       BoxTv()
                                    }
                                    .opacity(1.0)
                                    .padding([.bottom, .top], 40)
                            }.onAppear(){
                                self.player.play();
    }

有人能帮我吗?

推荐答案

在这个场景中,SwiftUI似乎失go 了与representable的连接...无论如何,最好在UIKit流中处理UIKit事情.代表性概念具有此类情况的协调器.

因此,一种可能的修复方法是将所有内容移到AVPlayerControllerRepresentable以内.

enter image description here

以下是主要部分(使用Xcode 13.4/iOS 15.5测试):

    func makeUIViewController(context: UIViewControllerRepresentableContext<AVPlayerControllerRepresentable>) -> AVPlayerViewController {
        let controller  = AVPlayerViewController()
        controller.player = player
        controller.showsPlaybackControls = false;

        context.coordinator.playerController = controller
        return controller
    }

    class Coordinator: NSObject, AVPlayerViewControllerDelegate {
        weak var playerController: AVPlayerViewController? {
            didSet {
                playerController?.delegate = self
            }
        }

        private var subscriber: AnyCancellable? = nil
        override init() {
            super.init()
            subscriber = NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)
                .sink { [weak self] _ in
                    self?.rotated()
                }
        }

        func rotated() {
            if UIDevice.current.orientation.isLandscape {
                self.enterFullScreen(animated: true)
            } else {
                self.exitFullScreen(animated: true)
            }
        }

    //...

Test module on GitHub

Ios相关问答推荐

React Native Text组件内部TextInput组件在iOS上的问题:在TextInput组件内部键入文本时失go 焦点

SwiftUI图表-默认情况下,X轴数据点的间距不相等

用于HDR显示的CI上下文选项

当操作修改查看条件时,按钮不重复

如何使用Swift以编程方式更改SVG文件中某些元素的 colored颜色

分配给指针会通过 class_addMethod 导致 EXC_BAD_ACCESS

无法向委托发送数据

SwiftUI:.toolbar 不适用于 UITextView

在 Swift 中,对象如何被准确地从内存中移除?

长按 SwiftUI 更改项目的顺序

RealityKit – ARView 光线投射返回 0 个结果

如何为视图的 colored颜色 和宽度设置动画?

带有属性包装器的不可用属性

AVPlayer 退出全屏

如何在保持纵横比的同时zoom UIView 的内容以适应目标矩形?

iOS 11 navigationItem.titleView 宽度未设置

Xcode 项目格式:3.1、3.2、6.3 和 8.0 有什么区别?

在 iOS 上存储身份验证令牌 - NSUserDefaults 与 keys 串?

比较没有时间分量的 NSDates

两个数字之间的动画UILabel文本?