Web app screen orientation lock: Orientation lock failed
1.) Screen.lockOrientation is deprecated (as seen in the MDN link you provided), so the code you have probably won't work in most modern browsers.
2.) ScreenOrientation is just the interface, which is why ScreenOrientation.lock("portrait")
does not work. Basically, ScreenOrientation is the thing in the background that tells the browser how the screen orientation object should be built (similar to prototypes in JavaScript), but it is not the object itself.
In modern browsers, you can access the global screen orientation like this:
var myScreenOrientation = window.screen.orientation;
(source: https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation)
Later you can lock the orientation with this:
myScreenOrientation.lock("portrait");
and unlock it with
myScreenOrientation.unlock();
The .lock() method returns a Promise if you want to do anything with that, but it's outside the scope of this question, so I'll just mention that it exists.
3.) Another possible issue: under current standards, many browsers will REQUIRE that a page be in fullscreen mode to lock a device's orientation. Since your web app is not fullscreen this will likely also prevent the orientation being locked. (see 5.3 of the web standard: https://www.w3.org/TR/screen-orientation/)
Check if device supports ScreenOrientation.lock() - Uncaught Error screen.orientation.lock() is not available on this device
window.screen.orientation.lock()
returns a Promise. A promise will call one of the functions that you provide to a chained then()
method, depending on whether the promise was resolved (success) or rejected (failure).
You could make your call to window.screen.orientation.lock()
like this:
window.screen.orientation
.lock("portrait")
.then(
success => console.log(success),
failure => console.log(failure)
)
You will probably want to put something more useful in the resolve
and reject
methods, but this will at least catch the rejection and prevent an Unhandled Rejection error from being thrown.
Flutter: How to set and lock screen orientation on-demand
First import the services package:
import 'package:flutter/services.dart';
This will give you access to the SystemChrome
class, which "Controls specific aspects of the operating system's graphical interface and how it interacts with the application."
When you load the Widget, do something like this:
@override
void initState(){
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
then when I leave the page, put it back to normal like this:
@override
dispose(){
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
How to enable screen orientation only on certain devices (e.g. iPads/tablets)?
I realized that you can check if the device is an iPad simply by using Platform
from react-native
. The complete solution is below:
expo-screen-orientation
needs to be installed
expo install expo-screen-orientation
and imported like this:
import * as ScreenOrientation from 'expo-screen-orientation';
Also, Platform
should be imported from react-native
import { Platform } from 'react-native';
After that, it's simply a matter of checking if the device is an iPad and if so unlock the orientation.
if (Platform.isPad) {
await ScreenOrientation.unlockAsync();
}
Note that changes will not be shown in the Expo app because that app has default orientation and it can't be locked (at least not on iOS).
Of course, in app.json
the orientation should be set to 'portrait'
"expo": {
...
"orientation": "portrait",
...
}
Update: Tested on Expo 36.0.0
and ScreenOrientation.unlockAsync()
is not supported. Worked after upgrading to 38.0.0
. Tested on 39.0.0.
, 40.0.0
and it works fine as well.
Additional Setup For Bare Workflows
For bare workflows additional setup is required.
Follow this tutorial from expo. Try building the app. If it fails make sure the import they stated is the second line just after #import "AppDelegate.h"
You should use the first option from their tutorial:
UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] init]; // The default screen orientation will be set to `portrait`.
Which will set the default orientation to portrait.
After that, you'll need to open your project in XCode and check that the app supports all four rotations
After that everything should work: App orientation is locked to portrait unless the person is on an iPad
Locking screen orientation in iOS 14
You cannot by any means prevent an iPad app that can assume all four rotational position from actually assuming all four rotational positions, unless you explicitly opt out of iPad multitasking.
To do so, set the Info.plist key UIRequiresFullScreen
to YES
; you can do that conveniently while editing the app target by checking Requires Full Screen in the General tab.
But Apple warns that this option is slated to be removed; multitasking will become a requirement and thus rotation to any position will be required as well. Basically it would be better to change your desires.
Related Topics
Android Sdk Asynctask Doinbackground Not Running (Subclass)
Creating Temporary Files in Android
Android: Binding Data from a Database to a Checkbox in a Listview
Eclipse Error "Adb Server Didn't Ack, Failed to Start Daemon"
How to Programmatically Turn Off Wifi on Android Device
Calling Startactivity() from Outside of an Activity
Locationsettingsrequest Dialog to Enable Gps - Onactivityresult() Skipped
Clear Back Stack Using Fragments
Different Font Size of Strings in the Same Textview
Creating an Android Trial Application That Expires After a Fixed Time Period
How to Read Value from String.Xml in Android
Pop Up Window Over Android Native Incoming Call Screen Like True Caller Android App
Round Corner for Bottomsheetdialogfragment
How to Add a Dropdown Item on the Action Bar
Android Imagebutton with a Selected State