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

iOS开发:强制AVPlayerViewController全屏横屏启动问题

解决AVPlayerViewController启动即强制全屏横屏的问题

我明白你的痛点——明明AVPlayerViewController能正常播放视频,翻转设备也能切换全屏,但就是没法让它一启动就直接进入横屏全屏状态。结合你Tab Bar+Navigation Controller的架构,给你几个关键步骤来搞定这个问题:

1. 先确保App和父视图控制器支持横屏

首先,你的App得允许横屏方向:

  • 打开Info.plist,添加UISupportedInterfaceOrientations数组,包含UIInterfaceOrientationPortrait、UIInterfaceOrientationLandscapeLeft、UIInterfaceOrientationLandscapeRight这三个值(如果不需要倒转就不用加UpsideDown)。

然后,在present AVPlayerViewController的那个ViewController里,重写屏幕旋转相关的属性,让它支持横屏:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    // 支持除了倒转以外的所有方向,或者直接写.landscape覆盖竖屏
    return .allButUpsideDown
}

override var shouldAutorotate: Bool {
    return true
}

如果你的ViewController是嵌套在Navigation Controller里的,别忘了自定义一个导航控制器,让它继承子控制器的旋转设置:

class CustomNavController: UINavigationController {
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return topViewController?.supportedInterfaceOrientations ?? .portrait
    }
    
    override var shouldAutorotate: Bool {
        return topViewController?.shouldAutorotate ?? true
    }
}

之后把Tab Bar里的导航控制器替换成这个自定义的。

2. 强制旋转屏幕+启动时进入全屏

接下来是核心操作:在present AVPlayerViewController之前,先强制把设备方向转到横屏,然后让播放器直接进入全屏模式。这里要适配iOS 16前后的API差异:

// 1. 先准备好你的AVPlayer实例
let videoURL = URL(string: "你的视频流地址")!
let player = AVPlayer(url: videoURL)
let playerVC = AVPlayerViewController()
playerVC.player = player

// 2. 禁止画中画,避免干扰全屏逻辑
playerVC.allowsPictureInPicturePlayback = false
// 设置视频填充模式为全屏填充
playerVC.videoGravity = .resizeAspectFill
// 必须设置为全屏present模式
playerVC.modalPresentationStyle = .fullScreen

// 3. 强制旋转屏幕(适配iOS 16+)
if #available(iOS 16.0, *) {
    if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .landscapeLeft)) { error in
            if let error = error {
                print("旋转失败:\(error.localizedDescription)")
            }
        }
    }
} else {
    // iOS 15及以下的旧方法
    UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}

// 4. present播放器,并在完成后强制进入全屏
present(playerVC, animated: true) {
    // 确保播放器已经准备好后再触发全屏
    if playerVC.player?.currentItem?.status == .readyToPlay {
        playerVC.enterFullscreen(animated: true)
    } else {
        // 如果还没准备好,监听状态变化后再全屏
        playerVC.player?.currentItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil)
    }
}

如果用了KVO监听状态,记得在deinit里移除观察者:

deinit {
    playerVC.player?.currentItem?.removeObserver(self, forKeyPath: "status")
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "status" {
        if let item = object as? AVPlayerItem, item.status == .readyToPlay {
            playerVC.enterFullscreen(animated: true)
            item.removeObserver(self, forKeyPath: "status")
        }
    }
}

3. 额外注意点

  • 不要在viewDidLoad里直接执行这段代码,最好放在用户触发的事件里(比如按钮点击),因为App启动初期屏幕旋转可能会有冲突。
  • 如果你的Tab Bar Controller限制了旋转,也要确保它支持横屏,或者在present播放器时临时放开限制。

这样操作后,AVPlayerViewController就能一启动就直接进入横屏全屏状态了,和翻转设备后的效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:38:47