Listen to device orientation changes in React Native applications and programmatically set preferred orientation on a per screen basis. Works on both Android and iOS.
npm install react-native-orientation --save
react-native link react-native-orientation
Please note that you still need to manually configure a couple files even when using automatic linking. Please see the 'Configuration' section below. You will also need to restart your simulator before the package will work properly.
iOS
- Add
node_modules/react-native-orientation/iOS/RCTOrientation.xcodeproj
to your xcode project, usually under theLibraries
group - Add
libRCTOrientation.a
(fromProducts
underRCTOrientation.xcodeproj
) to build target'sLinked Frameworks and Libraries
list - Add
$(SRCROOT)/node_modules/react-native-orientation/iOS/RCTOrientation/
toProject Name
->Build Settings
->Header Search Paths
Android
-
In
android/setting.gradle
... include ':react-native-orientation', ':app' project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
-
In
android/app/build.gradle
... dependencies { ... compile project(':react-native-orientation') }
-
Register module in
MainApplication.java
import com.github.yamill.orientation.OrientationPackage; // <--- import public class MainApplication extends Application implements ReactApplication { ...... @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new OrientationPackage() <------- Add this ); } ...... }
iOS
Add the following to your project's AppDelegate.m
:
#import "Orientation.h" // <--- import
@implementation AppDelegate
// ...
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [Orientation getOrientation];
}
@end
Android
Implement onConfigurationChanged
method in MainActivity.java
import android.content.Intent; // <--- import
import android.content.res.Configuration; // <--- import
public class MainActivity extends ReactActivity {
......
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
this.sendBroadcast(intent);
}
......
}
To use the react-native-orientation
package in your codebase, you should use the Orientation module:
import Orientation from "react-native-orientation";
export default class AppScreen extends Component {
// ...
componentWillMount() {
// The getOrientation method is async. It happens sometimes that
// you need the orientation at the moment the JS runtime starts running on device.
// `getInitialOrientation` returns directly because its a constant set at the
// beginning of the JS runtime.
const initial = Orientation.getInitialOrientation();
if (initial === 'PORTRAIT') {
// do something
} else {
// do something else
}
},
componentDidMount() {
// this locks the view to Portrait Mode
Orientation.lockToPortrait();
// this locks the view to Landscape Mode
// Orientation.lockToLandscape();
// this unlocks any previous locks to all Orientations
// Orientation.unlockAllOrientations();
Orientation.addOrientationListener(this._orientationDidChange);
},
_orientationDidChange = (orientation) => {
if (orientation === 'LANDSCAPE') {
// do something with landscape layout
} else {
// do something with portrait layout
}
},
componentWillUnmount() {
Orientation.getOrientation((err, orientation) => {
console.log(`Current Device Orientation: ${orientation}`);
});
// Remember to remove listener
Orientation.removeOrientationListener(this._orientationDidChange);
}
render() {
// ...
return (
// ...
)
}
}
-
Init the orientation to handle change events using your redux store :
import Orientation from "react-native-orientation";
const Store = initializeStore(); class YOUR_COMPONENT extends Component { constructor(props) { super(props); Orientation.init(Store); } }
-
Add the reducer to the combined reducers to make it mappable to your components' props :
import { OrientationReducer } from "react-native-orientation";
export default combineReducers({ // ... your other reducers orientation: OrientationReducer, });
-
Finaly, use it as the normal redux way by mapping it to your component props :
function mapStateToProps(state) { return { orientation: state.orientation.orientation, }; } export default connect(mapStateToProps, {})(YOUR_COMPONENT);
addOrientationListener(orientation => {});
orientation
will return one of the following values:
LANDSCAPE
PORTRAIT
PORTRAITUPSIDEDOWN
UNKNOWN
removeOrientationListener(orientation => {});
addSpecificOrientationListener(specificOrientation => {});
specificOrientation
will return one of the following values:
LANDSCAPE-LEFT
LANDSCAPE-RIGHT
PORTRAIT
PORTRAITUPSIDEDOWN
UNKNOWN
removeSpecificOrientationListener(specificOrientation => {});
lockToPortrait()
lockToLandscape()
lockToLandscapeLeft()
lockToLandscapeRight()
unlockAllOrientations()
getOrientation((err, orientation) => {})
getSpecificOrientation((err, specificOrientation) => {})