expo: [expo-screen-orientation] Screen orientation does not lock or trigger with EAS Build
Summary
On a built app with EAS build, calling https://docs.expo.dev/versions/latest/sdk/screen-orientation/#screenorientationlockasyncorientationlock does not trigger the screen to rotate and lock on iOS. When the app isn’t built with EAS build, and created with expo build, the screen orientation lock async function works.
Could possibly be related to: https://github.com/expo/expo/issues/11558
Managed or bare workflow? If you have ios/
or android/
directories in your project, the answer is bare!
managed
What platform(s) does this occur on?
iOS
SDK Version (managed workflow only)
43
Environment
Expo CLI 4.12.10 environment info: System: OS: macOS 11.6 Shell: 5.8 - /bin/zsh Binaries: Node: 14.15.1 - ~/.nvm/versions/node/v14.15.1/bin/node Yarn: 3.0.2 - ~/.nvm/versions/node/v14.15.1/bin/yarn npm: 6.14.8 - ~/.nvm/versions/node/v14.15.1/bin/npm Watchman: 2021.06.07.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: API Levels: 30, 31 Build Tools: 29.0.2, 30.0.2, 31.0.0 System Images: android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom, android-31 | Android TV Intel x86 Atom, android-31 | ARM 64 v8a, android-31 | Intel x86 Atom_64, android-31 | Google TV Intel x86 Atom, android-31 | Google APIs ARM 64 v8a, android-31 | Google APIs Intel x86 Atom_64, android-31 | Google Play ARM 64 v8a, android-31 | Google Play Intel x86 Atom_64 IDEs: Android Studio: 4.1 AI-201.8743.12.41.6953283 Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild npmPackages: expo: ^43.0.0 => 43.0.1 react: 17.0.1 => 17.0.1 react-dom: 17.0.1 => 17.0.1 react-native: 0.64.2 => 0.64.2 react-native-web: 0.17.1 => 0.17.1 npmGlobalPackages: expo-cli: 4.12.10 Expo Workflow: bare
Reproducible demo or steps to reproduce from a blank project
- Create a build with EAS Build for iOS
- Call the function https://docs.expo.dev/versions/latest/sdk/screen-orientation/#screenorientationlockasyncorientationlock
- Foregrounding/backgrounding the app and calling the function again does not trigger the screen to lock orientation.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 33
- Comments: 92 (9 by maintainers)
Experiencing the same issue. Used to work before transitioning to eas build, but now calling
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT)
does nothing.also using EAS and experiencing this behavior.
i can call
ScreenOrientation.unlockAsync()
and thenScreenOrientation.getPlatformOrientationLockAsync()
will returnhowever, the screen will not rotate when tilting the phone – made sure portrait lock was turned off on the phone too.
calling
ScreenOrientation.lockAsync(OrientationLock.LANDSCAPE_RIGHT)
does not have any effect either, but no errors are thrown.app.json does have
"orientation": "portrait"
; however, the expo-screen-orientation docs say it will override this and, at least from what it’s returning in thegetPlatformOrientationLockAsync
, it does seem to think it’s overriding it.edit: also did set
expo.ios.requireFullScreen = true
as the expo-screen-orientation docs say to do.Any update on this ? I understand that this is because the EAS uses a standalone app that runs on Android and iOS devices, and it doesn’t support some of the modules that are available in the standard Expo runtime.
Is there a workaround for this issue, or an alternative method that can be used to lock the screen orientation in an EAS project?
Also experiencing this issue on SDK 44 (EAS build) with no reliable workaround.
I see. Could be viable workaround to remove
"orientation": "portrait"
from app.json and then doScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP)
immediately after app start (e.g. in an effect in App.tsx). I will test this and share my findings.For me, adding
expo-sensors
as a dependency solved the issues I was having with this libraryDon’t forget to make a new development build after adding the new package
I also deleted the “orientation” param from app.json and instead configured the plugin like so:
I might be narrowing down the issue. It might be iOS 16 + using a modal presented view in ReactNavigation. I’ll see if I can create a minimal reproducible.
Can confirm that
ScreenOrientation.lockAsync
simply doesn’t do anything on iOS 16. No problems on Android or iOS <=15. The problem also occurs in the Expo Go app on iOS 16. My assumption is that @brycnguyen still uses iOS 15 in his iOS Simulator and therefor thought this problem only occurs in EAS Build apps. Can you confirm/decline @brycnguyen and update this issue’s title if this is the case?facing the same issue in 44
Still seeing this issue in Expo SDK44. Did an upgrade from 42 -> 43 -> 44. Readded Expo updates and still do not have any orientation working.
@watchinharrison exactly.
I removed
"orientation": "portrait"
fromapp.json
and lock the orientation on app start usingScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP)
. Then later I unlock/relock again using ScreenOrientation as needed.@AntonioGally This hook looks really nice! By the way, one thing I found after finishing my implementation is that positive and negative values for X and Y are flipped between Android and iOS (my implementation is correct for iOS devices).
I wanted to disable portrait mode on iPads and the following configuration worked for my case after trying lots of other options:
Same issue here in 44…
Same issue here in 44.
I’m facing similar problem with Expo 47, but there I have a little twist - if I do:
then it seems to reset screen orientation lock and from here on everything works as intended, but if I do just
then it does not. Problem is - locking and unlocking orientation like this results in ugly layout shifts which my client would never accept. I also tried:
but doing it like so won’t reset orientation locking.
EDIT:
I managed to find an interesting workaround for this issue, it looks like this:
Since
Dimensions
report orientation change just fine (they get updated on orientation change with or without lock), I was able to use it for orientation change detection and use screen width/height ratio to determine how should I lock orientation.It works nice, though keep in mind that by using it you limit your app to use only one landscape variant.
EDIT 2:
Above fix seemed nice, but it only worked on dev client, turns out this doesn’t work in standalone build. I ended up implementing my own screen orientation handler using Accelerometer, it looks like this:
Same request as for @Ahmed-Imam3 [so far it seems like there’s no solution yet?]
expo 46, still have this issue
Still an issue for us as of August 21. Have not found a reliable workaround
Edit: Expo 45
I’m running into the same issue on my iPad with a build with EAS, “expo-screen-orientation” as a dependency, and SDK45, this is the output:
On the one hand, the orientation does not respect my
app.config
definition since theexpo-screen-orientation
plugin produces modifications on theinfo.plist
so I put device-specific rules to override the values default(As seen in the screenshot) it seems that the
react-navigation
for some reason uses theportrait
mode (does this have something to do withEXDefaultScreenOrientationMask
coming from the plugin?), it also seems that the application is taking landscape mode correctly (but it’s not using my device-specific definition since it’s fixed to UIInterfaceOrientationLandscapeRight)on the other hand, if I remove the
expo-screen-orientation
dependency, everything works fine,I’ve been trying for days to find the perfect combination so that everything works perfectly, but I can’t get it,
I attach the output of
expo config --type introspect
in case it is useful:Click to expand!
I can confirm that the workaround mentioned above is working for me. App correctly stays locked in
PORTRAIT_UP
until I unlock or lock to a different orientation. Also no issues after backgrounding/foregrounding the app. I am using SDK 43 managed.These “same here”/“me too” comments aren’t helpful at all. Please consider only replying to issues with new information.
And for those who feel like it’s taking the maintainers too long to fix this: keep in mind that this is open-source software. Expo is a complex piece of software. If you want it fixed ASAP, create a pull request.
Hitting this issue now. I don’t use EAS build but lockAsync still does nothing on iOS 16.
After digging around the internets for quite a while I found this issue. Looks like using
setValue:forKey:
shouldn’t be used for setting the orientation from iOS 16 onwards.This solution only works in expo go , doesn’t work in IOS after doing EAS Build!
UPDATE: I found a workaround for the rotation issue on Android at app start by programmatically setting
orientation
toportrait
in myapp.config.ts
for Android, but leaving it out for iOS like this:There’s more in our config than that, obviously, but that’s the only thing I needed for the orientation.
process.env.PLATFORM
we set to eitherios
orandroid
during our build depending on the platform being built. It won’t be set when running in Expo Go so the orientation will end up being locked toportrait
. Which is fine since this issue only affects EAS built apps.We’ve seen screen orientation issues in 42, resolved in 43, and then reintroduced in 44. In our case we set app.config.js orientation: ‘landscape’ and lock the position in App.js using AppLoading component startAsync prop. In this case, we see the screen rotate erratically
a quick update, setting the expo.ios.infoPlist option in app.json to support landscape like so:
does enable rotating the screen into landscape.
however, expo-screen-orientation still fails to override the orientation locks at runtime to disable landscape orientation when it is not wanted.
so, i think this at least rules out landscape being disabled in the build settings as the reason that expo-screen-orientation could not allow landscape orientation, since it now cannot disallow landscape at runtime either.
@mvanroon thanks, I’ll try that
Just in case, https://github.com/yamill/react-native-orientation worked as expected for last 2 years almost without issues. Today I saw issue in Crashlytics on android 8 and decided to give expo-orientation another try (I tried to migrate 2 months ago and stumped into this issue that lib didn’t work as expected)
This code doesn’t help Orientation still unlocked
UPD. I switched to https://github.com/wonday/react-native-orientation-locker since couldn’t get expo-orientation working
Using this method I managed to solve our issues with expo-screen-orientation. Interestingly enough just adding expo-sensors as a dependency and removing the expo orientation param solved the problems we were having on ios. We did not test if the issue persisted on Expo GO, but it works on our latest EAS build.
The problem occurs when you try to change the screen orientation to landscape when switching to another page while the screen orientation is portrait. If you change the screen orientation on the same page (or screen) there would be no error. So my fix is to call the new page in portrait mode and put a timer. After the timer finish turn the screen. The error will be fixed.
You can add ActivityIndicator while the timer is working.
Same here. It seems to be not working properly since v44. https://github.com/expo/expo/issues/19690
There are repro steps with a snack for this issue in this other issue I filed: https://github.com/expo/expo/issues/21044
Also encountering this on SDK 47 with Expo Go and EAS builds on iPad 6, since upgrading it to iPadOS 16.1.1. The issue does not occur on our iPhone running iOS 15.5.
Has this been fixed in SDK 48? If so we will upgrade.
FYI, as of iOS 16, the
react-native-orientation
library & plugin I created no longer works. Seems like iOS 16 changed the way locking orientation works. It would be great if someone from the expo team took a look at this for expo-screen-orientation and see if it still works for iOS16My temporary solution to get rotation to work properly was,
App.tsx
For people looking for a solution, I ejected Expo and went with this one https://github.com/LyraHealth/react-native-orientation-plugin
Another alternative if you are using eas is to create a config-plugin to work with https://github.com/yamill/react-native-orientation. I’ve moved completely off expo-screen-orientation because of this bug.
Surprisingly even though the expo-screen-orientation library fails to detect orientation changes, DeviceMotion does not.
So, as a workaround for now if you only need 1 or a few screens to rotate like i did, you can listen for orientation changes from DeviceMotion in the expo-sensors library and rotate the screen yourself using reanimated (or whatever your animation library of choice is).
@silberistgold if you remove orientation option in app.json, it will work again… but its no good solution