yamill / react-native-orientation

Listen to device orientation changes in react-native and set preferred orientation on screen to screen basis.
https://www.npmjs.com/package/react-native-orientation
ISC License
1.72k stars 810 forks source link

IOS 16.1.1 deviceOrientationDidChange method is not called #418

Closed Itrainlcincom closed 1 year ago

Itrainlcincom commented 1 year ago

Hi. After update iOS 16.1.1 -> Orientation.addOrientationListener(_orientationDidChange) does not call _orientationDidChange

I have investigated in IOS, [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; } does not call deviceOrientationDidChange method.

How to fix this bug? Please help me.

On iOS 15.6.1

On iOS 16.1.1

pawansharmaAccolite commented 1 year ago

i am also facing same issue but for me its also not working in ios 15.6.1

my specs are

"react-native-orientation": "^3.1.3", "react": "17.0.1", "react-native": "0.64.1",

and in app deleagte

already imported orientation.h file in app delegate and method

(UIInterfaceOrientationMask)application:(UIApplication )application supportedInterfaceOrientationsForWindow:(UIWindow )window { return [Orientation getOrientation]; }

let me know if i am doing anything wrong and can you confirm in real device which have lower version then 16 its working or not

pawansharmaAccolite commented 1 year ago

Hi. After update iOS 16.1.1 -> Orientation.addOrientationListener(_orientationDidChange) does not call _orientationDidChange

I have investigated in IOS, [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; } does not call deviceOrientationDidChange method.

How to fix this bug? Please help me.

On iOS 15.6.1

  • Call lockToLandscape(RCT_EXPORT_METHOD(lockToLandscape)) -> deviceOrientationDidChange method is called.

On iOS 16.1.1

  • Call lockToLandscape(RCT_EXPORT_METHOD(lockToLandscape)) -> deviceOrientationDidChange method is not called.

@Itrainlcincom can you please confirm that its working fine in lower version device like ios 14 or 15 with xcode 13.1

Itrainlcincom commented 1 year ago

Hello. It is working fine in lower version, it is only error with 16.

This is code of me, it is working fine on all versions.

pawansharmaAccolite commented 1 year ago

@Itrainlcincom can you please share your complete file because its still not working for me on lower versions

pawansharmaAccolite commented 1 year ago

@Itrainlcincom this is my complete code and its working in ios 16 but not in lower versions

// // 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;

}

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]; }

@end

pawansharmaAccolite commented 1 year ago

@Itrainlcincom and in app delegate i have this

Itrainlcincom commented 1 year ago

Hi. You should use code from this library. https://www.npmjs.com/package/react-native-orientation-locker And custom Orientation.m // // react-native-orientation-locker // Orientation.m // // Created by Wonday on 17/5/12. // Copyright (c) wonday.org All rights reserved. //

import "Orientation.h"

@implementation Orientation {

if (!TARGET_OS_TV)

UIInterfaceOrientation _lastOrientation;
UIInterfaceOrientation _lastDeviceOrientation;
BOOL _disableFaceUpDown;

endif

BOOL _isLocking;

}

if (!TARGET_OS_TV)

static UIInterfaceOrientationMask _orientationMask = UIInterfaceOrientationMaskAll;

else

endif

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(configure:(NSDictionary *)options) {

if DEBUG

NSLog(@"Configure called with options: %@", options);

endif

if (!TARGET_OS_TV)

_disableFaceUpDown = [options objectForKey:@"disableFaceUpDown"] != nil;

endif

}

RCT_EXPORT_METHOD(getOrientation:(RCTResponseSenderBlock)callback) {

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    NSString *orientationStr = [self getOrientationStr:orientation];
    callback(@[orientationStr]);
}];

endif

}

RCT_EXPORT_METHOD(getDeviceOrientation:(RCTResponseSenderBlock)callback) {

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    UIInterfaceOrientation deviceOrientation = [self getDeviceOrientation];
    NSString *orientationStr = [self getOrientationStr:deviceOrientation];
    callback(@[orientationStr]);
}];

endif

}

RCT_EXPORT_METHOD(lockToPortrait) {

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationPortrait usingMask:UIInterfaceOrientationMaskPortrait];
}];

endif

}

RCT_EXPORT_METHOD(lockToPortraitUpsideDown) {

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationPortraitUpsideDown usingMask:UIInterfaceOrientationMaskPortraitUpsideDown];
}];

endif

}

RCT_EXPORT_METHOD(lockToLandscape)

{

if DEBUG

NSLog(@"Locking to Landscape");

endif

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {

    // set a flag so that no deviceOrientationDidChange events are sent to JS

// self->_isLocking = YES;

// UIInterfaceOrientation deviceOrientation = self->_lastDeviceOrientation;

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    NSString *orientationStr = [self getOrientationStr:orientation];

    // when call lockXXX, make sure to sent orientationDidChange event to JS

// [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationUnknown] forKey:@"orientation"];

    if ([orientationStr isEqualToString:@"LANDSCAPE-RIGHT"]) {
      [self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft];

// [Orientation setOrientation:UIInterfaceOrientationMaskLandscape]; // [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationLandscapeLeft] forKey:@"orientation"]; } else { [self lockToOrientation:UIInterfaceOrientationLandscapeRight usingMask:UIInterfaceOrientationMaskLandscapeRight]; // [Orientation setOrientation:UIInterfaceOrientationMaskLandscape]; // [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationLandscapeRight] forKey:@"orientation"]; }

    // restore device orientation

// [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: deviceOrientation] forKey:@"orientation"];

// [UIViewController attemptRotationToDeviceOrientation];

    // send a lock event

// [self sendEventWithName:@"lockDidChange" body:@{@"orientation":@"LANDSCAPE-LEFT"}];

// self->_isLocking = NO;

}];

// [[NSOperationQueue mainQueue] addOperationWithBlock:^ { // [self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft]; // }];

endif

}

RCT_EXPORT_METHOD(lockToLandscapeRight) {

if DEBUG

NSLog(@"Locking to Landscape Right");

endif

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft];
}];

endif

}

RCT_EXPORT_METHOD(lockToLandscapeLeft) {

if DEBUG

NSLog(@"Locking to Landscape Left");

endif

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationLandscapeRight usingMask:UIInterfaceOrientationMaskLandscapeRight];
}];

endif

}

RCT_EXPORT_METHOD(lockToAllOrientationsButUpsideDown) {

if DEBUG

NSLog(@"Locking to all except upside down");

endif

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationPortrait usingMask:UIInterfaceOrientationMaskAllButUpsideDown];
}];

endif

}

RCT_EXPORT_METHOD(unlockAllOrientations) {

if DEBUG

NSLog(@"Unlocking All Orientations");

endif

if (!TARGET_OS_TV)

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
    [self lockToOrientation:UIInterfaceOrientationUnknown usingMask:UIInterfaceOrientationMaskAll];
}];

endif

}

@end


In AppAppDelegate.m


In JS, you copy folder src from https://www.npmjs.com/package/react-native-orientation-locker (you download it) and paste to your project.


You use orientation in your code.

import Orientation, { useOrientationChange, useLockListener, useDeviceOrientationChange, } from "../../../src/hooks/index";


You read more document in https://www.npmjs.com/package/react-native-orientation-locker

This https://www.npmjs.com/package/react-native-orientation-locker is not working low version 16, I must be custom code in file orientation.m

Itrainlcincom commented 1 year ago

Hi. This library is not working with iOS 16 This https://www.npmjs.com/package/react-native-orientation-locker is not working low version 16. So I must custom code.