之前项目涉及到的都是竖屏的,没有涉及到横屏开发,这次遇到以竖屏为主 部分页面指定横屏,参考了网上的一些方案,终于测试出了一种比较合适的方案,因此将相关内容进行总结一下
01.综述
这次项目主要的页面时竖屏的,会存在连续2或3个页面横屏,在iOS系统16时无论是通过push还是present项目的动画和屏幕的旋转都很完美,但是在低于iOS系统16时push 完全无效果只能采用present模式,同时可以不受手机竖屏锁定
02.项目中设置的配置和代码
此处只选定竖屏一种模式
extension AppDelegate {
func application(_: UIApplication, supportedInterfaceOrientationsFor _: UIWindow?) -> UIInterfaceOrientationMask {
return .allButUpsideDown
}
}
extension UITabBarController {
// 是否支持自动转屏
override var shouldAutorotate: Bool {
guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.shouldAutorotate ?? false }
return navigationController.topViewController?.shouldAutorotate ?? false
}
// 支持哪些屏幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.supportedInterfaceOrientations ?? .portrait }
return navigationController.topViewController?.supportedInterfaceOrientations ?? .portrait
}
// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.preferredInterfaceOrientationForPresentation ?? .portrait }
return navigationController.topViewController?.preferredInterfaceOrientationForPresentation ?? .portrait
}
/// 状态栏样式
override var preferredStatusBarStyle: UIStatusBarStyle {
guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.preferredStatusBarStyle ?? .default }
return navigationController.topViewController?.preferredStatusBarStyle ?? .default
}
/// 是否隐藏状态栏
override var prefersStatusBarHidden: Bool {
guard let navigationController = selectedViewController as? UINavigationController else { return selectedViewController?.prefersStatusBarHidden ?? false }
return navigationController.topViewController?.prefersStatusBarHidden ?? false
}
}
extension UINavigationController {
// 是否支持自动转屏
override var shouldAutorotate: Bool {
return topViewController?.shouldAutorotate ?? false
}
// 支持哪些屏幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return topViewController?.supportedInterfaceOrientations ?? .portrait
}
// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return topViewController?.preferredInterfaceOrientationForPresentation ?? .portrait
}
/// 状态栏样式
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
/// 是否隐藏状态栏
override var prefersStatusBarHidden: Bool {
return topViewController?.prefersStatusBarHidden ?? false
}
}
基类
extension BaseViewController {
// 是否支持自动转屏
override var shouldAutorotate: Bool {
return false
}
// 支持哪些屏幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .portrait
}
/// 状态栏样式
override var preferredStatusBarStyle: UIStatusBarStyle {
return .default
}
/// 是否隐藏状态栏
override var prefersStatusBarHidden: Bool {
return false
}
}
//横屏 子类重写的方法
extension TestViewController{
// 支持哪些屏幕方向
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
}
竖屏跳转横屏
if #available(iOS 16.0, *) {
self.navigationController?.pushViewController(test, animated: true)
test.setNeedsUpdateOfSupportedInterfaceOrientations()
}else{
test.modalPresentationStyle = .fullScreen
self.present(sport, animated: true)
UIViewController.attemptRotationToDeviceOrientation()
}
一级横屏页面返回 竖屏
if #available(iOS 16.0, *) {
self.navigationController?.popViewController(animated: true)
}else{
self.dismiss(animated: true)
}
二级横屏页面返回 竖屏
if #available(iOS 16.0, *) {
self.navigationController?.popViewController(animated: true)
}else{
presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}