wonday / react-native-orientation-locker

A react-native module that can listen on orientation changing of device, get current orientation, lock to preferred orientation.
MIT License
758 stars 274 forks source link

Lock initial orientation natively (prior to javascript execution) #155

Open roni-castro opened 3 years ago

roni-castro commented 3 years ago

Assuming I want my application to always be locked to landscape on tablet devices, and I use Orientation.lockToLandscape() at the javascript index. If the user opens the app while the device is on portrait mode it will be opened on Portrait first and just after a period of time it will lock the orientation to Landscape. This behavior affects some views that depends on Dimensions that calculate the component's width/height. Can I set an initial orientation to make the app always start on landscape even when it is still on splash screen?

Apparently this is a similar problem of from the react-native-orientation library.

react-native-orientation-locker: 1.2.0

roni-castro commented 3 years ago

This is the only solution I have found to always lock tablets to landscape:

Android:

app/src/main/res/values/attrs.xml

<resources>
    <bool name="isTablet">false</bool>
</resources>

app/src/main/res/values-sw600dp/attrs.xml

<resources>
    <bool name="isTablet">true</bool>
</resources>

MainActivity:

import android.content.pm.ActivityInfo;
import android.os.Bundle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    boolean isTablet = getResources().getBoolean(R.bool.isTablet);
    if (isTablet) {
      setRequestedOrientation(
        ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
      );
    }
  }

iOS

AppDelegate.m

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
      return [Orientation getOrientation];
    } else {
      return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
    }
}
Covaks commented 3 years ago

@roni-castro your solution works great with tablets, but in my case I need to lock the screen in landscape mode on cold start only for all devices in iOS while still on splash screen and only after js is loaded pass control with return [Orientation getOrientation], otherwise my dynamic UI with Dimensions are affected, if device is in the PORTRAIT mode

AppDelegate.m

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  // need some logic here to detect cold start and pass first
  // return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
  // then let the library to control orientation from js
  return [Orientation getOrientation];
}

In Android it is very simple to achieve with android:screenOrientation="landscape"

Does anyone know solution for it?

msantang78 commented 3 years ago

For iOS adding this at the beginning of the didFinishLaunchingWithOptions method did the trick for me

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Set initial orientation
[Orientation setOrientation:UIInterfaceOrientationMaskPortrait];