横竖屏的转换,既可以手动操作实现,也可以自动旋转设备实现。 情况1:APP项目所有页面既支持横屏,又支持竖屏。 在项目配置中设置了支持横竖屏,则不需要对视图等做过多的配置即可实现横竖屏。如图所示: 情况2:APP项目根据需要,个别页面需要既支持横屏,又支持竖屏。 在项目配置中设置了只支持竖屏。如图所示:
实现逻辑
示例代码: 1、AppDelegate.h中定义是否允许旋转的变量
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; /** * 是否允许转向 */ @property (nonatomic, assign) BOOL allowRotation; @end2、AppDelegate.m中实现旋转的代理方法
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window { if (self.allowRotation) { // 横竖屏 return UIInterfaceOrientationMaskAllButUpsideDown; } else { // 竖屏 return UIInterfaceOrientationMaskPortrait; } }3、在需要支持横竖屏旋转的页面实现相关方法 (1)进入视图控制器时,允许横竖屏
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // 允许横竖屏 AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; appDelegate.allowRotation = YES; }(2)离开视图控制器时,恢复竖屏
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // 恢复竖屏 AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; appDelegate.allowRotation = NO; }(3)在视图控制器中实现如下方法(实际上发现貌似没有执行,且屏蔽掉后也不影响横竖屏切换。)
// 方法1 决定当前界面是否开启自动转屏,如果返回NO,后面两个方法也不会被调用,只是会支持默认的方向 - (BOOL)shouldAutorotate { return YES; } // 方法2 返回支持的旋转方向 - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; } // 方法3 返回进入界面默认显示方向 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; }target-action方式实现横竖屏转换 1、实现UIDevice的类别新增方法
#import <UIKit/UIKit.h> @interface UIDevice (Launch) + (void)switchNewOrientation:(UIInterfaceOrientation)interfaceOrientation; @end #import "UIDevice+Launch.h" @implementation UIDevice (Launch) + (void)switchNewOrientation:(UIInterfaceOrientation)interfaceOrientation { NSNumber *resetOrientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationUnknown]; [[UIDevice currentDevice] setValue:resetOrientationTarget forKey:@"orientation"]; // NSNumber *orientationTarget = [NSNumber numberWithInt:interfaceOrientation]; [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"]; } @end2、AppDelegate中定义变量,并实现横竖屏控制
// AppDelegate.h中定义变量 是否允许转向 @property (nonatomic, assign) BOOL allowRotation; // AppDelegate.m中实现方法 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window { if (self.allowRotation) { // 横竖屏 return UIInterfaceOrientationMaskAllButUpsideDown; } else { // 竖屏 return UIInterfaceOrientationMaskPortrait; } }3、target-action实现横竖屏切换
// 手动操作横竖屏 UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithTitle:@"左" style:UIBarButtonItemStyleDone target:self action:@selector(leftClick)]; UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithTitle:@"右" style:UIBarButtonItemStyleDone target:self action:@selector(rightClick)]; UIBarButtonItem *protrait = [[UIBarButtonItem alloc] initWithTitle:@"竖" style:UIBarButtonItemStyleDone target:self action:@selector(protraitClick)]; self.navigationItem.rightBarButtonItems = @[left,right,protrait]; - (void)protraitClick { AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; // 允许转成竖屏 appDelegate.allowRotation = NO; // 调用n竖屏屏代码 [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait]; } - (void)leftClick { AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; // 允许转成横屏 appDelegate.allowRotation = YES; // 调用横屏代码 [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeLeft]; } - (void)rightClick { AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; // 允许转成横屏 appDelegate.allowRotation = YES; // 调用横屏代码 [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight]; }4、当前视图控制器返回前一个视图控制器时,需要恢复竖屏模式
- (void)backClick { AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; // 允许转成竖屏 appDelegate.allowRotation = NO; // 调用竖屏代码 [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait]; [self.navigationController popViewControllerAnimated:YES]; }横竖屏切换后的页面适配 1、在视图控制器中
// 屏幕旋转之后,屏幕的宽高互换,我们借此判断重新布局 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; if (size.width > size.height) { // 横屏设置,为防止遮挡键盘,调整输入视图的高度 } else { // 竖屏设置 } }2、在视图抽象类中
- (void)layoutSubviews { [super layoutSubviews]; // 通过状态栏电池图标来判断屏幕方向 if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationMaskPortrait) { // 竖屏 balabala } else { // 横屏 balabala } }