橫豎屏的轉換及頁面適配

橫豎屏的轉換,既可以手動操作實現,也可以自動旋轉設備實現。
情況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;

@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
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章