# 12.一键搞定iOS16横竖屏切换

### 前言

近期同事反馈视频横屏的功能失效了，在才发现 `iOS16` 下以前的方式无法使用了。于是完善了一些自己之前写的横竖屏切换的拓展。

### 一、 iOS16 之前

#### 1.1 切换横屏

```swift
UIDevice.current.setValue(UIDeviceOrientation.landscapeLeft.rawValue, forKey: "orientation")
```

#### 1.2 切换竖屏

```swift
UIDevice.current.setValue(UIDeviceOrientation.portrait.rawValue, forKey: "orientation")
```

#### 1.3 切换结果监听

通过系统通知 `UIDevice.orientationDidChangeNotification` 监听提切换动作。

```swift
@objc
private func orientationDidChange(noti: Notification) {
    guard
        let device = noti.object as? UIDevice
    else {
        return
    }
    if device.orientation.isLandscape {
        print("横屏")
    } else {
        print("竖屏")
    }
}
```

### 二、 iOS16

更新了 `iOS16` 之后，发现上面的都没效果了，就...很可爱。iOS16 之后需要通过 Scene 来进行横竖屏的切换控制。

核心代码如下：

```
func enterFullScreen() {
    guard #available(iOS 16.0, *) else {
        UIDevice.current.setValue(UIDeviceOrientation.landscapeLeft.rawValue, forKey: "orientation")
        return
    }
    switchMode(full: true)
}

func exitFullScreen() {
    guard #available(iOS 16.0, *) else {
        UIDevice.current.setValue(UIDeviceOrientation.portrait.rawValue, forKey: "orientation")
        return
    }
    switchMode(full: false)
}

@available(iOS 16.0, *)
private func switchMode(full: Bool) {
    guard
        let scence = UIApplication.shared.connectedScenes.first as? UIWindowScene
    else {
        return
    }
    let orientation: UIInterfaceOrientationMask = full ? .landscape : .portrait
    let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation)
    scence.requestGeometryUpdate(geometryPreferencesIOS) { error in
    }
}
```

### 三、RyukieSwifty/FullScreen

![iOS16](/files/v2AlDkBXmXxouYQsTHry)

我对这些逻辑进行了封装可以简单的接入到项目之中。也提供了示例程序。[GitHub: RyukieSwifty/FullScreen](https://github.com/RyukieSama/Swifty#34-横竖屏切换)

`pods` 接入：

`pod 'RyukieSwifty/FullScreen'`

下面以一个 `UIViewController` 为例：

```
import UIKit
import RyukieSwifty

class FullScreenViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    // MARK: - Life
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        swifty.exitFullScreen()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        swifty.needFullScreen()
    }
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        if size.width > size.height {
            switchButton.isSelected = true
        } else {
            switchButton.isSelected = false
        }
    }
    // MARK: - Function-Public
    
    // MARK: - Function-Private
    
    // MARK: UI
    private func setupUI() {
        view.backgroundColor = .white
        
        switchButton
            .added(to: view)
            .layout { make in
                make?.center.equalToSuperview()
            }
    }
    
    // MARK: Buiness
    
    // MARK: Action
    @objc
    private func switchAction() {
        switchButton.isSelected ? swifty.exitFullScreen() : swifty.enterFullScreen()
    }
    
    // MARK: Request
    
    // MARK: - VarLet-Public
    
    // MARK: - VarLet-Private
    private lazy var switchButton: UIButton = {
        return UIButton()
            .config {
                $0.setTitleColor(.black, for: .normal)
                $0.setTitle("切换为横屏", for: .normal)
                $0.setTitle("切换为竖屏", for: .selected)
                $0.addTarget(self, action: #selector(switchAction), for: .touchUpInside)
            }
    }()
}

extension AppDelegate {
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return application.swifty.supportedInterfaceOrientations
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryukiedev.gitbook.io/wiki/ios/you-hua/12.-yi-jian-gao-ding-ios16-heng-shu-ping-qie-huan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
