在 Android 中,我们如果想实现某个 Activity 支持或者不支持横竖屏切换,只需要在清单文件 AndroidManifest.xml 中配置一下即可,但是 iOS 却不是配置的,要稍微麻烦一丢丢,需要我们在代码中配置。
我们的应用大部分是大部分界面只需要竖屏显示,某些特殊界面如视频播放、拍照等界面才需要支持旋转,所以我们只需要封装成应用默认竖屏,支持单个 ViewController 设置支持旋转即可。
一、单个 ViewController 旋转
1.配置应用支持旋转
首先我们需要在项目配置中支持旋转,否则代码中无论怎么修改都是旋转不了的。
2.AppDelegate
AppDelegate 中我们设置为默认不支持旋转,这样应用就默认竖屏了。
//
// AppDelegate.swift
// CloudConference
//
// Created by 覃浩 on 2023/2/22.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
/**
默认不允许旋转
*/
var allowRotate = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.backgroundColor = UIColor.white
window?.rootViewController = UINavigationController(rootViewController: SplashViewController())
window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if (allowRotate) {
return .all
} else {
return .portrait
}
}
}
3.单个 ViewController 设置支持旋转
如果我们想要某个 ViewController 支持横竖屏切换的话,只需要 viewDidAppear 中修改 AppDelegate 的 allowRotate 值为 true 即可,需要注意在该界面消失时,需要将 allowRotate 值修改回来,而且还需要手动将应用重置为竖屏状态,否则返回到上一界面还会是横屏状态,导致显示不正常。
//
// SplashViewController.swift
// CloudConference
//
// Created by zst on 2023/3/27.
//
import UIKit
class SplashViewController: CCViewController<SplashPresenter>, SplashView, ViewControllerProtocol {
override func viewDidAppear(_ animated: Bool) {
// 允许屏幕旋转
(UIApplication.shared.delegate as! AppDelegate).allowRotate = true
}
override func viewWillDisappear(_ animated: Bool) {
// 禁止屏幕旋转
(UIApplication.shared.delegate as! AppDelegate).allowRotate = false
// 切回竖屏
let orientation = NSNumber(integerLiteral: UIInterfaceOrientation.portrait.rawValue)
UIDevice.current.setValue(orientation, forKey: "orientation")
}
}
二、监听屏幕旋转
我们有时候还需要监听屏幕的旋转,只需要通过 NotificationCenter.default.addObserver() 添加观察者即可,在该界面消失时同样记得移除该观察者。
//
// SplashViewController.swift
// CloudConference
//
// Created by zst on 2023/3/27.
//
import UIKit
class SplashViewController: CCViewController<SplashPresenter>, SplashView, ViewControllerProtocol {
override func viewDidAppear(_ animated: Bool) {
// 允许屏幕旋转
(UIApplication.shared.delegate as! AppDelegate).allowRotate = true
// 开始生成设备方向通知
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
// 添加方向改变观察者
NotificationCenter.default.addObserver(self, selector: #selector(onOrientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
// 禁止屏幕旋转
(UIApplication.shared.delegate as! AppDelegate).allowRotate = false
// 切回竖屏
let orientation = NSNumber(integerLiteral: UIInterfaceOrientation.portrait.rawValue)
UIDevice.current.setValue(orientation, forKey: "orientation")
// 移除方向改变观察者
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
// 停止生成设备方向通知
UIDevice.current.endGeneratingDeviceOrientationNotifications()
}
@objc private func onOrientationChanged() {
print("屏幕方向发生了改变, UIDevice.current.orientation---\(UIDevice.current.orientation)")
switch(UIDevice.current.orientation) {
case.unknown: print("未知")
case .portrait: print("竖屏")
case .portraitUpsideDown: print("竖屏倒置")
case .landscapeLeft: print("横屏逆时针")
case .landscapeRight: print("横屏顺时针")
case .faceUp: print("平放向上")
case .faceDown: print("平放向下")
@unknown default: break
}
}
}