IOS
[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()
#import
#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
Android
Android Video横屏沉浸式全屏解决方法:
https://gitee.com/jerry_ee/ImmersionBar .
使用:
1、在android/app/build.gradle android依赖下添加如下代码
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2'
2、在AndroidManifest.xml中添加
3、API基础用法,在MainActivity.java的 onCreate 中添加,别忘了引入,最好是用Android studio打开ctrl + 左键 import class
import com.gyf.immersionbar.BarHide;
import com.gyf.immersionbar.ImmersionBar;
ImmersionBar.with(this).init();
ImmersionBar.with(this).hideBar(BarHide.FLAG_HIDE_BAR);