Lock iPad Orientation to Portrait

Please provide the following:

  1. SDK Version: 45
  2. Platforms(Android/iOS/web/all): Android/iOS

I am building an App for Android and iOS, and want to lock the orientation to Protrait. It is ok for both Android and iOS phone, but somehow iPad can still turn to Landscape. I have set app.json like below:

“expo”: {
“name”: “xx”,
“slug”: “xxx”,
“version”: “1.0.0”,
“orientation”: “portrait”,
“ios”: {
“supportsTablet”: true,
“infoPlist”: {
“UISupportedInterfaceOrientations~ipad”: [
“UIInterfaceOrientationPortrait”
]
}

…}

Are there any other settings for iPad I need to add?

Thanks a lot in advance!

Hi @rachellauyui,
are you running on Expo Go?

Hi @outatime! No, I am running Dev Client on iPad.

Did you try to build an internal distribution (“preview”), without developer client, to see if it respects your orientation settings?

Another thing I forgot, by any chance do you have a dependency on expo-screen-orientation?

Hi, I did not install expo-screen-orientation. Sorry I am not sure what is an internal distribution (“preview”), without developer client.

I just check infoPlist, it is like this:
UISupportedInterfaceOrientations~ipad

UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight

It contains all 4 orientation so I suppose this is why iPad orientation is not locked. Not sure how to remove the 3 other orientations though…

Probably in your eas.json you have the following entries:

{
  "cli": {
    "version": ">= 0.52.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview"
    },
    "production": {
      "channel": "production"
    },
    "simulator": {
      "ios": {
        "simulator": true
      }
    }
  },
  "submit": {
    "production": {}
  }
}

the preview profile does not use the development client even though it is included in the project.

I recommend you make a build using that profile to see what the behavior of the orientation in the following way:

$ eas build --profile preview --platform ios --clear-cache
1 Like

I think that might be the solution. There’s some reference in the docs to different behaviour on iPad.

Hi @wodin and @outatime ! Unfortunately, both do not work… I suppose it is the native info.plist has the final say on orientation. And the iPad orientation is still all 4 directions in info.plist.

I haven’t tested it myself, but the documentation says:

ScreenOrientation from expo allows changing supported screen orientations at runtime, and subscribing to orientation changes. This will take priority over the orientation key in app.json.

I would have expected the app.json setting to generate the setting(s) in Info.plist. So I would interpret the above to mean that ScreenOrientation is supposed to override the settings in Info.plist.

But it goes on to say:

Apple added support for split view mode to iPads in iOS 9. This changed how the screen orientation is handled by the system. To put the matter shortly, for the iOS, your iPad is always in the landscape mode unless you open two applications side by side. In order to be able to lock screen orientation using this module you will need to disable support for this feature. For more information about the split view mode, check out the official Apple documentation.

I’m not sure I understand that fully. I do not own an iPad and have not read Apple’s split view docs. But it sounds like the app would be forced to landscape mode unless you open it in split screen mode, or you disable the split screen feature.

You say your app can switch to landscape, rather than being forced to landscape mode, though, so maybe you have already disabled split screen mode?

If the problem is with the Info.plist file, then it might be that there’s a config plugin doing that.

If I were you I would run expo prebuild -p ios to generate the native iOS project files. (Make sure your project is committed to Git first so you can easily revert the changes afterwards.) Then check the Info.plist to see what it contains.

Then I would dig arould in the expo/expo-cli, expo/expo, expo/config-plugins repositories for a config plugin that might be adding the orientation settings to Info.plist.

Once you know where it’s coming from you could probably use patch-package or a config plugin of your own to fix it.

But if app.json and ScreenOrientation are not working and you can create a small example that demonstrates the problem, I suggest you create an issue in the expo/expo github repository.

Hi @rachellauyui

I’ve been poking around in the expo-cli source code a bit and have found something that might explain what’s going on.

If I run expo prebuild -p ios in one of my test SDK 45 apps I get the following in Info.plist. (I do not have anything to do with requireFullScreen in app.json and I left the default "orientation":"portrait" as-is):

[...]
    <key>UIRequiresFullScreen</key>
    <false/>
[...]
    <key>UISupportedInterfaceOrientations</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationPortraitUpsideDown</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationPortraitUpsideDown</string>
      <string>UIInterfaceOrientationLandscapeLeft</string>
      <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
[...]

And in packages/config-plugins/src/ios/RequiresFullScreen.ts I found the following:

After adding "requireFullScreen":"true" to the "ios" section and running expo prebuild -p ios --clean I get the following:

[...]
    <key>UIRequiresFullScreen</key>
    <true/>
[...]
    <key>UISupportedInterfaceOrientations</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationPortraitUpsideDown</string>
    </array>
[...]

I haven’t tested it, but it looks promising.

1 Like

Sorry Michael @wodin, somehow I missed your reply!

It WORKS!!! THANK YOU SOSOSO MUCH!! I will give it 10 hearts if I can.

I am not totally following the logic. Do you mean that Orientation does not work in iPAD unless “requireFullScreen” is set to false?

1 Like

Hi @rachellauyui

No, I mean the opposite. It does not work unless requireFullScreen is set to true. By default (in recent versions of the Expo SDK) it defaults to false, so if you want to specify the orientation you have to set it to true.

From the code it seems that if requireFullScreen is false then you have to specify all possible orientations. Otherwise Apple will reject the submission with an “Invalid Bundle” error saying that “iPad Multitasking” (presumably split screen mode) requires all of the orientations.

So to avoid this error Expo is automatically adding all orientations to the iPad orientation in Info.plist if requireFullScreen is false. Regardless of what you specify for orientation.

I hope that clarifies the situation :slight_smile:

EDIT: If it does, maybe you could propose some better wording for the documentation so that the next person can figure it out without having to resort to reading the Expo code?

1 Like

@wodin Typo. I mean requireFullScreen set to “true”. Yes, this is very clear! I suppose your explanation could be put on documentation, under a section called “iPAD orientation”?

BTW, I stumble upon this → Expo Tools - Visual Studio Marketplace

So, in order to take a look on info.plist, I no longer need to do the whole pre-build clear thing. If you are using Visual Basic, just install this tool, View → Command Pallette → Expo: Preview Modifier → ios.infoPlist.

That is, and you can see your info.plist without pre-build or eject (and the afterward deleting files etc). What is even more amazing is that it is hot refresh. I mean, once you change some app.json or plugin file, it is immediately reflected in the infoplist preview!! Wow, save me so much time!

Ah yes, you’re right. I don’t use VS Code, so I’ve never tried that.

Cool! :slight_smile:

Apparently coming soon to the next version of the Expo Tools for VS Code:

More intellisense, more typo protections

We now have autocomplete + validation for eas.json, app.json, store.config.json, and expo-module.config.json

1 Like

Cool, looking forward to the next release!

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.