yamill/react-native-orientation

Orientation listener not longer firing after calling lockToPortrait() or lockToLandscape()

pouyaemami opened this issue · 5 comments

Pretty much what the title says. When I lock the orientation in any direction, the event listener for the orientation change is no longer fired until I call unlockAllOrientations. I'm not sure if this is the expected behaviour. The example code seems to suggest otherwise as it locks the screen on componentDidMount.

Here's my code:

export default class App extends Component {
  state = {
    showCard: false
  }

  constructor() {
    super()

    Instabug.startWithToken(Config.INSTABUG_TOKEN, [
      Instabug.invocationEvent.floatingButton
    ])
  }

  componentWillMount() {
    Orientation.lockToPortrait()
    Orientation.addOrientationListener(this.orientationDidChange)
  }

  componentWillUnmount() {
    Orientation.removeOrientationListener(this.orientationDidChange)
  }

  orientationDidChange = (orientation) => {
    const showCard = orientation === 'LANDSCAPE'
    this.setState({ showCard })
  }

  render() {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <SwitchNavigatorContainer />
          {this.state.showCard && <LandscapeWallet>
            <Wallet orientation='LANDSCAPE' />
          </LandscapeWallet>}
          <AppMessage />
          <OfflineSnack />
        </PersistGate>
      </Provider>
    )
  }
}

Since the orientation is locked in portrait mode, the event listener will never fire when the phone is in landscape mode and therefore the showCard will never be set to true.

Cheers

@pouyaemami I'm curious to if you're running this on iOS.

I just installed and set up this package in my project and I got the exact same thing. I could set orientation and the change would fire, but it wouldn't unlock.

I'm asking if you're on iOS because if you added this from the configuration:

//AppDelegate.m

#import "Orientation.h" 
...
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
  while ([[UIDevice currentDevice] isGeneratingDeviceOrientationNotifications]) {
      [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
  }

  return [Orientation getOrientation];
}

I resolved this issue by commenting out the while loop that unsubscribes:

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
//  while ([[UIDevice currentDevice] isGeneratingDeviceOrientationNotifications]) {
//      [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
//  }

  return [Orientation getOrientation];
}

Unsure if that will help you or not, but it helped me move past this initial hurdle. If you found another solution I'd love to hear it.

@deefourple thanks for the tip! I am using both Android and iOS. I'm not sure where I would make a similar change for Android though 🤔

One more thing, I just looked at my AppDelegate.m file and I don't have the same thing as you. This is what I have and it's working as expected:

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

@pouyaemami I haven't actually tested android yet as I wanted to ensure this worked for iOS first.

Actually, in terms of the AppDelegate.m code if you remove the commented out part in my example, we do share the same code :).

The while loop was definitely messing up the orientationDidChange for me. If I find any issues/discoveries for android I'll be sure to reach out.

Is it possible to disable the orientation listener when the device orientation is locked to portrait? I don't want my layout changing when it should be fixed in one orientation.