美文网首页
iOS 设置屏幕方向

iOS 设置屏幕方向

作者: 芮淼一线 | 来源:发表于2023-07-31 20:34 被阅读0次

    iOS设置屏幕方向代码示例

    UIDevice+Orientation.h
    #import <UIKit/UIKit.h>
    
    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 <UIKit/UIKit.h>
    
    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 设置屏幕方向

          本文链接:https://www.haomeiwen.com/subject/netypdtx.html