横竖屏的转换及页面适配

横竖屏的转换,既可以手动操作实现,也可以自动旋转设备实现。
情况1:APP项目所有页面既支持横屏,又支持竖屏。
在项目配置中设置了支持横竖屏,则不需要对视图等做过多的配置即可实现横竖屏。如图所示:
横竖屏的转换及页面适配_第1张图片
情况2:APP项目根据需要,个别页面需要既支持横屏,又支持竖屏。
在项目配置中设置了只支持竖屏。如图所示:
横竖屏的转换及页面适配_第2张图片

实现逻辑

示例代码:
1、AppDelegate.h中定义是否允许旋转的变量

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

/**
 * 是否允许转向
 */
@property (nonatomic, assign) BOOL allowRotation;

@end

2、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"];
}

@end

2、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
    }
}

你可能感兴趣的:(iOS,开发编码收集,iOS,适配,iOS,硬件设备,iOS,视图控制器)