How can I disable rotation only for specific views (e.g: when using Navigator) and not for the entire app?
The question here already addresses disabling rotation for the entire app
How can I disable rotation only for specific views (e.g: when using Navigator) and not for the entire app?
The question here already addresses disabling rotation for the entire app
With the react-native-orientation
package, it's possible to lock the orientation to portrait/landscape. The package and documentation can be found here: https://github.com/yamill/react-native-orientation
Remember; you should not put your locking inside the rendering of scenes (nor the renderScene
method). Since the Navigator re-renders all the scenes in the route stack, this would probably cause weird side effects for you. Rather, the locking/unlocking should be put in the code that interacts with the route stack (ie. calls the push
/pop
methods).
If your case is about more specific control over orientations of different screens in StackNavigator (something like Portrait -> LandscapeLeft -> LandscapeRight -> Portrait
, and all the way back), here is a may-not-that-pretty solution:
define base screens as follow:
// baseScreen.js
import React, { Component } from "react";
import Orientation from "react-native-orientation";
export class PortraitScreen extends Component {
constructor(props) {
super(props);
this._willFocusSubscription = this.props.navigation.addListener("willFocus", payload => {
// lock to portrait when this screen is about to appear
Orientation.lockToPortrait();
})
}
componentWillUnmount() {
// remove subscription when unmount
this._willFocusSubscription.remove();
}
}
export class LandscapeScreen extends Component {
constructor(props) {
super(props);
this._willFocusSubscription = this.props.navigation.addListener("willFocus", payload => {
// lock to landscape
Orientation.lockToLandscape();
})
}
componentWillUnmount() {
// remove subscription either
this._willFocusSubscription.remove();
}
}
define concrete screens which extends abovementioned base screen(s):
// moduleScreens.js
import React from "react";
import { Button, View } from "react-native";
import { PortraitScreen, LandscapeScreen } from "/path/to/baseScreen";
export class VideoDescScreen extends PortraitScreen {
render() {
return (
<View>
<Button
title="watch video"
onPress={() => this.props.navigation.navigate("VideoPlayer")}
/>
</View>
)
}
}
export class VideoPlayerScreen extends LandscapeScreen {
render() {
return <View>...</View>
}
}
create route like this:
// route.js
import React from "react";
import { createStackNavigator } from "react-navigation";
import { VideoDescScreen, VideoPlayerScreen } from "/path/to/moduleScreens";
const stack = createStackNavigator(
{
VideoDesc: {
screen: VideoDescScreen
},
VideoPlayer: {
screen: VideoPlayerScreen
}
}
)
How it works? According to doc, we observe event willFocus
when screen is initialized, and each time this screen is about to appear (focused) in navigation, we lock device to our desired orientation, works for both PUSH(to) and POP(back from) behaviors.
Hope it helps.