UIViewControllerRotation
屏幕旋转控制类,耦合性低,但由于使用了runtime,所以具有侵入性,
使用情况
当前市场上大多数应用程序并非所有页面都可以旋转屏幕,通常只有少数几个页面需要旋转屏幕,例如查看文档、观看视频等界面。这个扩展因此而生,专门用于管理旋转状态,默认所有界面都禁止旋转,需要旋转的界面只需要重写系统方法即可。
为什么使用 OC
如果按照一般的写法,需要以下步骤
- 就应该创建
BaseViewController
、BaseNavigationController
、BaseTabBarController
这三个基类, - 修改它们的
shouldAutorotate
、supportedInterfaceOrientations
、preferredInterfaceOrientationForPresentation
方法来实现个别界面的旋转效果
但这样做会使项目的耦合性非常大,需要所有类都继承这些基类
因此考虑采用扩展方法实现,但由于 Swift 的扩展不支持重写父类方法,所以这里使用 OC 实现
从 Xcode 11 开始遇到一个问题:iOS13 在 debug 连接模拟器/真机调试时无法触发 Category 重写系统的一些方法(但不影响 release 包),因此从 3.0.0
版本开始,完全使用 Swizzle 的形式实现功能
添加方法
- 将文件拖拽到项目中
- 使用 cocoapods 引入,在 Podfile 中添加
pod 'UIViewControllerRotation'
使用方法
在需要旋转的界面中重写以下方法即可,耦合性非常低:
shouldAutorotate
默认返回true
supportedInterfaceOrientations
默认返回UIInterfaceOrientationMaskPortrait
preferredInterfaceOrientationForPresentation
默认返回UIInterfaceOrientationPortrait
preferredStatusBarStyle
默认返回UIStatusBarStyleDefault
prefersStatusBarHidden
默认返回false
如果想要修改默认值, 请查看UIViewControllerRotateDefault
类遵循以下要求
OC:
[UIViewControllerRotateDefault shared].defaultShouldAutorotate = NO;
Swift:
UIViewControllerRotateDefault.shared.defaultShouldAutorotate = false
PS.如果某些类需要强制修改方向,需要使用UIViewControllerRotationModel
进行设置
目前已包含以下内部类:
- AVFullScreenViewController
- AVPlayerViewController
- AVFullScreenPlaybackControlsViewController
- WebFullScreenVideoRootViewController
- UISnapshotModalViewController
风险提示
本扩展使用runtime替换了以下方法,如果出现冲突,请自行修改或寻找其他解决方案
- UIViewController
- @selector(shouldAutorotate)
- @selector(supportedInterfaceOrientations)
- @selector(preferredInterfaceOrientationForPresentation)
- @selector(preferredStatusBarStyle)
- @selector(prefersStatusBarHidden)
- @selector(childViewControllerForStatusBarStyle)
- @selector(childViewControllerForStatusBarHidden)
- @selector(viewWillAppear:)
- UINavigationController
- @selector(shouldAutorotate)
- @selector(supportedInterfaceOrientations)
- @selector(preferredInterfaceOrientationForPresentation)
- @selector(preferredStatusBarStyle)
- @selector(prefersStatusBarHidden)
- @selector(childViewControllerForStatusBarStyle)
- @selector(childViewControllerForStatusBarHidden)
- @selector(pushViewController:animated:)
- @selector(popToViewController:animated:)
- @selector(popToRootViewControllerAnimated:)
- UITabBarController
- @selector(shouldAutorotate)
- @selector(supportedInterfaceOrientations)
- @selector(preferredInterfaceOrientationForPresentation)
- @selector(preferredStatusBarStyle)
- @selector(prefersStatusBarHidden)
- @selector(childViewControllerForStatusBarStyle)
- @selector(childViewControllerForStatusBarHidden)
- @selector(setSelectedIndex:)
- @selector(setSelectedViewController:)
- UIApplication
- @selector(setDelegate:)
- UIApplication.delegate
- @selector(application:supportedInterfaceOrientationsForWindow:)强制返回ALL,否则会导致presented的界面dismiss时crash
作者
Kagen,[email protected]
许可证
UIViewControllerRotation根据MIT许可证提供。有关更多信息,请参阅LICENSE文件。