# 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](https://4193904735-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MI8JgbGh3U6X_oedqkm%2Fuploads%2Fgit-blob-76feaf8f8c8ef808d7d4320e8b2b48678eb5b0b2%2F12-01.gif?alt=media)

我对这些逻辑进行了封装可以简单的接入到项目之中。也提供了示例程序。[GitHub: RyukieSwifty/FullScreen](https://github.com/RyukieSama/Swifty#34-%E6%A8%AA%E7%AB%96%E5%B1%8F%E5%88%87%E6%8D%A2)

`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
    }
}
```
