美文网首页
react-native-orientation横竖屏适配 iO

react-native-orientation横竖屏适配 iO

作者: 物联白菜 | 来源:发表于2022-12-09 15:06 被阅读0次

    [IOS 16+] [Orientation] BUG IN CLIENT OF UIKIT: Setting UIDevice.orientation is not supported. Please use UIWindowScene.requestGeometryUpdate(_:)

    修复:
    在github官网issues有人修复了,但是请求合并到react-native-orientation库还没有同意,所以需要自己找到这个文件修改替换一下代码,附上issues链接:https://github.com/yamill/react-native-orientation/pull/413/commits/e37a2639438e9b90b2f5d8dcf955b630b2639295#

    步骤:在node_modules/react-native-orientation/iOS/RCTOrientation/Orientation.m文件,把下面的代码全选替换整个Orientation.m文件的代码重新跑项目即可。

    //
    //  Orientation.m
    //
    
    #import "Orientation.h"
    #if __has_include(<React/RCTEventDispatcher.h>)
    #import <React/RCTEventDispatcher.h>
    #else
    #import "RCTEventDispatcher.h"
    #endif
    
    @implementation Orientation
    @synthesize bridge = _bridge;
    
    static UIInterfaceOrientationMask _orientation = UIInterfaceOrientationMaskAllButUpsideDown;
    + (void)setOrientation: (UIInterfaceOrientationMask)orientation {
      _orientation = orientation;
    }
    + (UIInterfaceOrientationMask)getOrientation {
      return _orientation;
    }
    
    - (instancetype)init
    {
      if ((self = [super init])) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];
      }
      return self;
    
    }
    
    - (void)dealloc
    {
      [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    + (BOOL)requiresMainQueueSetup
    {
      return YES;
    }
    
    - (void)dispatchOrientationChangeEvent:(UIDeviceOrientation)orientation {
        [self.bridge.eventDispatcher sendDeviceEventWithName:@"specificOrientationDidChange"
                                                    body:@{@"specificOrientation": [self getSpecificOrientationStr:orientation]}];
    
        [self.bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange"
                                                    body:@{@"orientation": [self getOrientationStr:orientation]}];
    }
    
    - (void)lockToOrientationWithMask:(UIInterfaceOrientationMask)maskOrientation interfaceOrientation:(UIInterfaceOrientation)interfaceOrientation deviceOrientation:(UIDeviceOrientation)deviceOrientation {
        if (@available(iOS 16, *)) {
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
                UIWindowScene *scene = (UIWindowScene *)array[0];
                [UIViewController attemptRotationToDeviceOrientation];
                UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:maskOrientation];
                [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {}];
            });
            [self dispatchOrientationChangeEvent:deviceOrientation];
        } else {
            [[NSOperationQueue mainQueue] addOperationWithBlock:^ {
                [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
                [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:interfaceOrientation] forKey:@"orientation"];
            }];
        }
    }
    
    - (void)deviceOrientationDidChange:(NSNotification *)notification
    {
        UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
        [self dispatchOrientationChangeEvent:orientation];
    }
    
    - (NSString *)getOrientationStr: (UIDeviceOrientation)orientation {
      NSString *orientationStr;
      switch (orientation) {
        case UIDeviceOrientationPortrait:
          orientationStr = @"PORTRAIT";
          break;
        case UIDeviceOrientationLandscapeLeft:
        case UIDeviceOrientationLandscapeRight:
    
          orientationStr = @"LANDSCAPE";
          break;
    
        case UIDeviceOrientationPortraitUpsideDown:
          orientationStr = @"PORTRAITUPSIDEDOWN";
          break;
    
        default:
          // orientation is unknown, we try to get the status bar orientation
          switch ([[UIApplication sharedApplication] statusBarOrientation]) {
            case UIInterfaceOrientationPortrait:
              orientationStr = @"PORTRAIT";
              break;
            case UIInterfaceOrientationLandscapeLeft:
            case UIInterfaceOrientationLandscapeRight:
    
              orientationStr = @"LANDSCAPE";
              break;
    
            case UIInterfaceOrientationPortraitUpsideDown:
              orientationStr = @"PORTRAITUPSIDEDOWN";
              break;
    
            default:
              orientationStr = @"UNKNOWN";
              break;
          }
          break;
      }
      return orientationStr;
    }
    
    - (NSString *)getSpecificOrientationStr: (UIDeviceOrientation)orientation {
      NSString *orientationStr;
      switch (orientation) {
        case UIDeviceOrientationPortrait:
          orientationStr = @"PORTRAIT";
          break;
    
        case UIDeviceOrientationLandscapeLeft:
          orientationStr = @"LANDSCAPE-LEFT";
          break;
    
        case UIDeviceOrientationLandscapeRight:
          orientationStr = @"LANDSCAPE-RIGHT";
          break;
    
        case UIDeviceOrientationPortraitUpsideDown:
          orientationStr = @"PORTRAITUPSIDEDOWN";
          break;
    
        default:
          // orientation is unknown, we try to get the status bar orientation
          switch ([[UIApplication sharedApplication] statusBarOrientation]) {
            case UIInterfaceOrientationPortrait:
              orientationStr = @"PORTRAIT";
              break;
            case UIInterfaceOrientationLandscapeLeft:
            case UIInterfaceOrientationLandscapeRight:
    
              orientationStr = @"LANDSCAPE";
              break;
    
            case UIInterfaceOrientationPortraitUpsideDown:
              orientationStr = @"PORTRAITUPSIDEDOWN";
              break;
    
            default:
              orientationStr = @"UNKNOWN";
              break;
          }
          break;
      }
      return orientationStr;
    }
    
    RCT_EXPORT_MODULE();
    
    RCT_EXPORT_METHOD(getOrientation:(RCTResponseSenderBlock)callback)
    {
      UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
      NSString *orientationStr = [self getOrientationStr:orientation];
      callback(@[[NSNull null], orientationStr]);
    }
    
    RCT_EXPORT_METHOD(getSpecificOrientation:(RCTResponseSenderBlock)callback)
    {
      UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
      NSString *orientationStr = [self getSpecificOrientationStr:orientation];
      callback(@[[NSNull null], orientationStr]);
    }
    
    RCT_EXPORT_METHOD(lockToPortrait)
    {
      #if DEBUG
        NSLog(@"Locked to Portrait");
      #endif
        [Orientation setOrientation:UIInterfaceOrientationMaskPortrait];
        [self lockToOrientationWithMask:UIInterfaceOrientationMaskPortrait interfaceOrientation:UIInterfaceOrientationPortrait deviceOrientation:UIDeviceOrientationPortrait];
    }
    
    RCT_EXPORT_METHOD(lockToLandscape)
    {
      #if DEBUG
        NSLog(@"Locked to Landscape");
      #endif
      UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
      NSString *orientationStr = [self getSpecificOrientationStr:orientation];
      if ([orientationStr isEqualToString:@"LANDSCAPE-LEFT"]) {
          [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeRight];
          [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeRight interfaceOrientation:UIInterfaceOrientationLandscapeRight deviceOrientation:UIDeviceOrientationLandscapeRight];
      } else {
          [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeLeft];
          [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeLeft interfaceOrientation:UIInterfaceOrientationLandscapeLeft deviceOrientation:UIDeviceOrientationLandscapeLeft];
      }
    }
    
    RCT_EXPORT_METHOD(lockToLandscapeLeft)
    {
      #if DEBUG
        NSLog(@"Locked to Landscape Left");
      #endif
        [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeLeft];
        [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeLeft interfaceOrientation:UIInterfaceOrientationLandscapeLeft deviceOrientation:UIDeviceOrientationLandscapeLeft];
    
    }
    
    RCT_EXPORT_METHOD(lockToLandscapeRight)
    {
      #if DEBUG
        NSLog(@"Locked to Landscape Right");
      #endif
       [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeRight];
       [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeRight interfaceOrientation:UIInterfaceOrientationLandscapeRight deviceOrientation:UIDeviceOrientationLandscapeRight];}
    
    RCT_EXPORT_METHOD(unlockAllOrientations)
    {
      #if DEBUG
        NSLog(@"Unlock All Orientations");
      #endif
        UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
        [Orientation setOrientation:UIInterfaceOrientationMaskAllButUpsideDown];
        [self lockToOrientationWithMask:UIInterfaceOrientationMaskAllButUpsideDown interfaceOrientation:UIInterfaceOrientationMaskAllButUpsideDown deviceOrientation:orientation];
    }
    
    - (NSDictionary *)constantsToExport
    {
    
      UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
      NSString *orientationStr = [self getOrientationStr:orientation];
    
      return @{
        @"initialOrientation": orientationStr
      };
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:react-native-orientation横竖屏适配 iO

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