iOS 设置屏幕方向

iOS设置屏幕方向代码示例

UIDevice+Orientation.h
#import 

NS_ASSUME_NONNULL_BEGIN

@interface UIDevice ()
/** 设置屏幕方向,小于iOS16 */
- (void)setOrientation:(UIInterfaceOrientation)orientation API_DEPRECATED("iOS16+使用setOrientationIOS16:", ios(2.0, 16.0));
@end

@interface UIDevice (Orientation)
/** 设置屏幕方向,iOS16+ */
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation API_AVAILABLE(ios(16.0));
- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler API_AVAILABLE(ios(16.0));
@end

NS_ASSUME_NONNULL_END
UIDevice+Orientation.m
#import "UIDevice+Orientation.h"

@implementation UIDevice (Orientation)

- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation
{
    [self setOrientationIOS16:orientation errorHandler:nil];
}

- (void)setOrientationIOS16:(UIInterfaceOrientationMask)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler
{
    if(@available(iOS 16.0,*)){
        UIWindowScene *scene = (UIWindowScene *)UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
        UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
        geometryPreferences.interfaceOrientations = orientation;
        if(errorHandler){
            [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:errorHandler];
        }else{
            [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
                NSLog(@"屏幕旋转失败: %@",error);
            }];
        }
    }
}
@end

优化版本(推荐使用)

UIDevice+Orientation.h
#import 

NS_ASSUME_NONNULL_BEGIN

/**
 用于设置UI界面方向的自定义枚举值
 */
typedef NS_ENUM(NSInteger, TKInterfaceOrientation){
    TKInterfaceOrientationPortrait,
    TKInterfaceOrientationPortraitUpsideDown,
    TKInterfaceOrientationLandscapeLeft,
    TKInterfaceOrientationLandscapeRight
};


@interface UIDevice (Orientation)
/** 手动设置屏幕方向 */
- (void)setUIOrientation:(TKInterfaceOrientation)orientation;
/** 手动设置屏幕方向,新增错误操作回调 */
- (void)setUIOrientation:(TKInterfaceOrientation)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler;
@end

NS_ASSUME_NONNULL_END
UIDevice+Orientation.m
#import "UIDevice+Orientation.h"

@interface UIDevice ()
/**
 功能:设置屏幕方向,小于iOS16(手动旋转)
 说明: 直接使用扩展来访问是有方法,即只声明不实现。
 注意: 如果出现上架错误请直接使用以前的老方法实现。
 */
- (void)setOrientation:(UIInterfaceOrientation)orientation API_DEPRECATED("iOS16+使用setOrientationIOS16:", ios(2.0, 16.0));
@end

@implementation UIDevice (Orientation)

- (void)setUIOrientation:(TKInterfaceOrientation)orientation
{
    [self setUIOrientation:orientation errorHandler:nil];
}

- (void)setUIOrientation:(TKInterfaceOrientation)orientation errorHandler:(nullable void (^)(NSError *error))errorHandler
{
    NSInteger realOrientation = [self obtainOrientationRealValueWith:orientation];
    if(@available(iOS 16.0,*)){
        UIWindowScene *scene = (UIWindowScene *)UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
        UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
        geometryPreferences.interfaceOrientations = realOrientation;
        if(errorHandler){
            [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:errorHandler];
        }else{
            [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
                NSLog(@"屏幕旋转失败: %@",error);
            }];
        }
    }else{
        [self setOrientation:realOrientation];
    }
}

/**
 根据不同的系统版本获取TKInterfaceOrientation枚举对应的真实值
 */
- (NSInteger)obtainOrientationRealValueWith:(TKInterfaceOrientation)orientation
{
    NSInteger real = 0;
    if(@available(iOS 16.0,*)){
        switch (orientation) {
            case TKInterfaceOrientationPortrait:
                real = UIInterfaceOrientationMaskPortrait;
                break;
            case TKInterfaceOrientationPortraitUpsideDown:
                real = UIInterfaceOrientationMaskPortraitUpsideDown;
                break;
            case TKInterfaceOrientationLandscapeLeft:
                real = UIInterfaceOrientationMaskLandscapeLeft;
                break;
            case TKInterfaceOrientationLandscapeRight:
                real = UIInterfaceOrientationMaskLandscapeRight;
                break;
        }
    }else{
        switch (orientation) {
            case TKInterfaceOrientationPortrait:
                real = UIInterfaceOrientationPortrait;
                break;
            case TKInterfaceOrientationPortraitUpsideDown:
                real = UIInterfaceOrientationPortraitUpsideDown;
                break;
            case TKInterfaceOrientationLandscapeLeft:
                real = UIInterfaceOrientationLandscapeLeft;
                break;
            case TKInterfaceOrientationLandscapeRight:
                real = UIInterfaceOrientationLandscapeRight;
                break;
        }
    }
    return real;
}

@end


解释

扩展了一个没有实现的方法:setOrientation:(UIInterfaceOrientation)orientation,来支持iOS16以下的屏幕方向设置。
这种写法就是使用了OC扩展的特性来访问私有方法。
不使用传统方式调用其目的就是简化代码,如果审核不通过就是用老的方式进行调用即可。

参考

iOS16适配-屏幕旋转 - (jianshu.com)

你可能感兴趣的:(iOS 设置屏幕方向)