Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ This is the log of notable changes to the Expo client that are developer-facing.
- Enriched `androidStatusBar` configuration in `app.json`. ([#6506](https://github.com/expo/expo/pull/6506) [@bbarthec](https://github.com/bbarthec))
- Extended `androidNavigationBar.visible` configuration in `app.json`. To keep the same behavior as before, change your `androidNavigationBar.visible` field from `false` to `leanback`. ([#7049](https://github.com/expo/expo/pull/7049) [@cruzach](https://github.com/cruzach))
- **`expo`**: Removed `AuthSession` from the `expo` package and extracted into `expo-auth-session` unimodule. ([#6989](https://github.com/expo/expo/pull/6989) by [@lukmccall](https://github.com/lukmccall))
- **`expo`**: Removed `ScreenOrientation` from the `expo` package and extracted into `expo-screen-orientation` unimodule. ([#6760](https://github.com/expo/expo/pull/6760) by [@lukmccall](https://github.com/lukmccall))
- Removed `Orientation.PORTRAIT` and `Orientation.LANDSCAPE` from `ScreenOrientation` in favor of their more specific versions. ([#6760](https://github.com/expo/expo/pull/6760) by [@lukmccall](https://github.com/lukmccall))

### 🎉 New features

Expand Down
106 changes: 66 additions & 40 deletions docs/pages/versions/unversioned/sdk/screen-orientation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: ScreenOrientation
sourceCodeUrl: 'https://github.com/expo/expo/tree/sdk-36/packages/expo/src/ScreenOrientation'
sourceCodeUrl: 'https://github.com/expo/expo/tree/sdk-37/packages/expo-screen-orientation'
---

import InstallSection from '~/components/plugins/InstallSection';
Expand All @@ -20,15 +20,38 @@ On both iOS and Android platforms, changes to the screen orientation will overri

<InstallSection packageName="expo-screen-orientation" />

### Warning

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](https://support.apple.com/en-us/HT207582).

#### Managed workflow

Open your `app.json` and add the following inside of the `"expo"` field:

```json
{
"expo": {
...
"ios": {
...
"requireFullScreen": true,
}
}
}
```

#### Bare workflow

Tick the `Requires Full Screen` checkbox in Xcode. It should be located under `Project Target > General > Deployment Info`.

## API

```js
import { ScreenOrientation } from 'expo';
import * as ScreenOrientation from 'expo-screen-orientation';
```

### Methods

- [`ScreenOrientation.allowAsync(orientationLock)`](#screenorientationallowasyncorientationlock)
- [`ScreenOrientation.lockAsync(orientationLock)`](#screenorientationlockasyncorientationlock)
- [`ScreenOrientation.lockPlatformAsync(platformInfo)`](#screenorientationlockplatformasyncplatforminfo)
- [`ScreenOrientation.unlockAsync()`](#screenorientationunlockasync)
Expand Down Expand Up @@ -64,26 +87,6 @@ import { ScreenOrientation } from 'expo';

## Methods

### `ScreenOrientation.allowAsync(orientationLock)`

Deprecated in favor of `ScreenOrientation.lockAsync`. Allow a screen orientation.

#### Arguments

- **orientation (_OrientationLock_)** -- The orientation lock to apply. See the [`OrientationLock`](#screenorientationorientationlock) enum for possible values.

#### Returns

Returns a promise with `void` value, resolving when the orientation is set.

#### Example

```javascript
function changeScreenOrientation() {
await ScreenOrientation.allowAsync(ScreenOrientation.Orientation.LANDSCAPE);
}
```

### `ScreenOrientation.lockAsync(orientationLock)`

Lock the screen orientation to a particular OrientationLock.
Expand All @@ -100,6 +103,7 @@ Returns a promise with `void` value, resolving when the orientation is set.

- `ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK` - an invalid [`OrientationLock`](#screenorientationorientationlock) was passed in.
- `ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK` - the platform does not support the orientation lock policy.
- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

#### Example

Expand All @@ -121,13 +125,18 @@ Returns a promise with `void` value, resolving when the orientation is set and r

#### Error Codes

- `ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK` - an invalid [`OrientationLock`](#screenorientationorientationlock) was passed in.
- `ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK` - an invalid [`OrientationLock`](#screenorientationorientationlock) was passed in (**iOS only**).
- `ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK` - the platform does not support the orientation lock policy.
- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

### `ScreenOrientation.unlockAsync()`

Sets the screen orientation back to the `OrientationLock.DEFAULT` policy.

#### Error Codes

- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

#### Returns

Returns a promise with `void` value, resolving when the orientation is set.
Expand All @@ -140,6 +149,11 @@ Gets the current screen orientation.

Returns a promise that resolves to an [`OrientationInfo`](#screenorientationorientationinfo) object value that reflects the current screen orientation.

#### Error Codes

- `ERR_SCREEN_ORIENTATION_GET_ORIENTATION_LOCK` - An unknown error occurred when trying to get the system lock. (**Android only**)
- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

### `ScreenOrientation.getOrientationLockAsync()`

Gets the current screen orientation lock type.
Expand All @@ -148,6 +162,10 @@ Gets the current screen orientation lock type.

Returns a promise with an [`OrientationLock`](#screenorientationorientationlock) value.

#### Error Codes

- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

### `ScreenOrientation.getPlatformOrientationLockAsync()`

Gets the platform specific screen orientation lock type.
Expand All @@ -156,6 +174,11 @@ Gets the platform specific screen orientation lock type.

Returns a promise with a [`PlatformOrientationInfo`](#screenorientationplatformorientationinfo) value.

#### Error Codes

- `ERR_SCREEN_ORIENTATION_GET_PLATFORM_ORIENTATION_LOCK`
- `ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY` - could not get the current activity (**Android only**).

### `ScreenOrientation.supportsOrientationLockAsync(orientationLock)`

Returns whether the [`OrientationLock`](#screenorientationorientationlock) policy is supported on the device.
Expand All @@ -166,7 +189,7 @@ Returns a promise that resolves to a `boolean` value that reflects whether or no

### `ScreenOrientation.addOrientationChangeListener(listener)`

Invokes the `listener` function when the screen orientation changes.
Invokes the `listener` function when the screen orientation changes from `portrait` to `landscape` or from `landscape` to `portrait`. For example, it won't be invoked when screen orientation change from `portrait up` to `portrait down`, but it will be called when there was a change from `portrait up` to `landscape left`.

#### Arguments

Expand Down Expand Up @@ -195,10 +218,8 @@ Unsubscribes the listener associated with the `subscription` object from all ori
### `ScreenOrientation.Orientation`

- **`Orientation.UNKNOWN`** - An unknown screen orientation. For example, the device is flat, perhaps on a table.
- **`Orientation.PORTRAIT`** - Portrait interface orientation (right side up or upside down).
- **`Orientation.PORTRAIT_UP`** - Right-side up portrait interface orientation.
- **`Orientation.PORTRAIT_DOWN`** - Upside down portrait interface orientation.
- **`Orientation.LANDSCAPE`** - Landscape interface orientation (right or left).
- **`Orientation.LANDSCAPE_LEFT`** - Left landscape interface orientation.
- **`Orientation.LANDSCAPE_RIGHT`** - Right landscape interface orientation.

Expand All @@ -217,6 +238,8 @@ An enum whose values can be passed to the [`lockAsync`](#screenorientationlockas
- **`OrientationLock.OTHER`** -- A platform specific orientation. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).
- **`OrientationLock.UNKNOWN`** -- An unknown screen orientation lock. This is not a valid policy that can be applied in [`lockAsync`](#screenorientationlockasyncorientationlock).

> **Note** `OrientationLock.ALL` and `OrientationLock.PORTRAIT` are invalid on devices which don't support `OrientationLock.PORTRAIT_DOWN`.

### `ScreenOrientation.SizeClassIOS`

Each iOS device has a default set of [size classes](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html) that you can use as a guide when designing your interface.
Expand All @@ -242,20 +265,20 @@ An enum representing the lock policies that can be applied on the web platform,

### `ScreenOrientation.PlatformOrientationInfo`

- screenOrientationConstantAndroid (_integer_): A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation). For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED), -1 should be passed in. (Android only)
- screenOrientationArrayIOS (Array[Orientation]): An array of orientations to allow on the iOS platform (iOS only)
- screenOrientationLockWebOrientation (_WebOrientationLock_): A web orientation lock to apply in the browser (web only)
- **screenOrientationConstantAndroid (_integer_)**: A constant to set using the Android native [API](https://developer.android.com/reference/android/R.attr.html#screenOrientation). For example, in order to set the lock policy to [unspecified](https://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_UNSPECIFIED), -1 should be passed in. (**Android only**)
- **screenOrientationArrayIOS (Array[Orientation])**: An array of orientations to allow on the iOS platform (**iOS only**)
- **screenOrientationLockWebOrientation (_WebOrientationLock_)**: A web orientation lock to apply in the browser (**web only**)

### `ScreenOrientation.OrientationInfo`

- orientation (_Orientation_): The current orientation of the device
- verticalSizeClass (_SizeClassIOS_): The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html) of the device (iOS only)
- horizontalSizeClass (_SizeClassIOS_): The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html) of the device (iOS only)
- **orientation (_Orientation_)**: The current orientation of the device
- **verticalSizeClass (_SizeClassIOS_)**: The [vertical size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html) of the device (**iOS only**)
- **horizontalSizeClass (_SizeClassIOS_)**: The [horizontal size class](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/TheAdaptiveModel.html) of the device (**iOS only**)

### `ScreenOrientation.OrientationChangeEvent`

- orientationLock (_OrientationLock_): The current OrientationLock of the device.
- orientationInfo (_OrientationInfo_): The current OrientationInfo of the device.
- **orientationLock (_OrientationLock_)**: The current OrientationLock of the device.
- **orientationInfo (_OrientationInfo_)**: The current OrientationInfo of the device.

### `Subscription`

Expand All @@ -267,15 +290,18 @@ A [subscription object](https://github.com/expo/expo/blob/master/packages/expo-r

#### Args

- event (_OrientationChangeEvent_): An update with the most recent OrientationChangeEvent.
- **event (_OrientationChangeEvent_)**: An update with the most recent OrientationChangeEvent.

#### Returns

`void`

## Error Codes

| Code | Description |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK | The platform does not support the [`OrientationLock`](#screenorientationorientationlock) policy. |
| ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK | An invalid [`OrientationLock`](#screenorientationorientationlock) was passed in. |
| Code | Description |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK | The platform does not support the [`OrientationLock`](#screenorientationorientationlock) policy. |
| ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK | An invalid [`OrientationLock`](#screenorientationorientationlock) was passed in. |
| ERR_SCREEN_ORIENTATION_GET_ORIENTATION_LOCK | An unknown error occurred when trying to get the system lock. (**Android only**) |
| ERR_SCREEN_ORIENTATION_GET_PLATFORM_ORIENTATION_LOCK | An unknown error occurred when trying to get the system lock. (**Android only**) |
| ERR_SCREEN_ORIENTATION_MISSING_ACTIVITY | Could not get the current activity. (**Android only**) |
29 changes: 27 additions & 2 deletions packages/expo-screen-orientation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,37 @@ npm install expo-screen-orientation

### Configure for iOS

Run `pod install` in the ios directory after installing the npm package.
1. Run `pod install` in the ios directory after installing the npm package.
2. Open the `AppDelegate.m` of your application.
3. Import `<EXScreenOrientation/EXScreenOrientationViewController.h>`
4. In `-application:didFinishLaunchingWithOptions:launchOptions` change default `root view controller` to `EXScreenOrientationViewController`:

Replace

```objc
UIViewController *rootViewController = [UIViewController new];
```

with:

```objc
UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] init]; // The default screen orientation will be set to `portrait`.
```

or if you want to change the default screen orientation, with:

```objc
UIViewController *rootViewController = [[EXScreenOrientationViewController alloc] initWithDefaultScreenOrientationMask:UIInterfaceOrientationMaskPortrait]; // through parameter you can specify your default orientation mask.
```

For more information about available orientation masks, check out [UIInterfaceOrientationMask](https://developer.apple.com/documentation/uikit/uiinterfaceorientationmask?language=objc)

> **Note** if you are using a custom view controller, the controller will need to extend the `EXScreenOrientationViewController`.

### Configure for Android

No additional set up necessary.

# Contributing

Contributions are very welcome! Please refer to guidelines described in the [contributing guide]( https://github.com/expo/expo#contributing).
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
return reject(@"ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK", [NSString stringWithFormat:@"Invalid screen orientation lock %@", orientationLock], nil);
}
if (![EXScreenOrientationUtilities doesDeviceSupportOrientationMask:orientationMask]) {
return reject(@"ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK", [NSString stringWithFormat:@"This device does not support this orientation %@", orientationLock], nil);
return reject(@"ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK", [NSString stringWithFormat:@"This device does not support the requested orientation %@", orientationLock], nil);
}

[_screenOrientationRegistry setMask:orientationMask forModule:self];
Expand All @@ -66,9 +66,17 @@ - (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
for (NSNumber *allowedOrientation in allowedOrientations) {
UIInterfaceOrientation orientation = [EXScreenOrientationUtilities importOrientation:allowedOrientation];
UIInterfaceOrientationMask orientationMask = [EXScreenOrientationUtilities maskFromOrientation:orientation];
if (!orientationMask) {
return reject(@"ERR_SCREEN_ORIENTATION_INVALID_ORIENTATION_LOCK", @"Invalid screen orientation lock.", nil);
}

allowedOrientationsMask = allowedOrientationsMask | orientationMask;
}

if (![EXScreenOrientationUtilities doesDeviceSupportOrientationMask:allowedOrientationsMask]) {
return reject(@"ERR_SCREEN_ORIENTATION_UNSUPPORTED_ORIENTATION_LOCK", @"This device does not support the requested orientation.", nil);
}

[_screenOrientationRegistry setMask:allowedOrientationsMask forModule:self];
resolve(nil);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

@interface EXScreenOrientationViewController : UIViewController

- (instancetype)init;

- (instancetype)initWithDefaultScreenOrientationMask:(UIInterfaceOrientationMask)defaultOrientationMask;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ @interface EXScreenOrientationViewController ()

@implementation EXScreenOrientationViewController

- (instancetype)init
{
return [self initWithDefaultScreenOrientationMask:UIInterfaceOrientationMaskPortrait];
}

- (instancetype)initWithDefaultScreenOrientationMask:(UIInterfaceOrientationMask)defaultOrientationMask
{
if (self = [super init]) {
Expand Down