React-native: <Modal /> doesn't handle screen sizes and orientations properly

Created on 23 May 2016  路  30Comments  路  Source: facebook/react-native

So today I was trying to refactor my code to migrate from a custom imperative Modal API to React Native's <Modal /> and found some issues which made me write my own component in JS instead.

  • [x] Modal's height doesn't include the statusbar, so when the app has a translucent statusbar, Modal is drawn under the statusbar and there's empty space left at the bottom
  • [x] Modal is not responsive to orientation, even if the device is in landscape mode, Modal is drawn according to potrait mode, so it kinda covers half the screen and the bottom part gets hidden
  • [ ] It would be nice if the native Modal could respond to screen size and orientation change like a JS based Modal does
  • [ ] With the slide animation, the animating Modal has a strip at the top which resembles the statusbar for some reason
Good first issue Help Wanted Locked

Most helpful comment

i found that this is not a bug, as shown on the doc Modal section
https://facebook.github.io/react-native/docs/modal.html
we need to set the supportedOrientation prop of the Modal to ['portrait', 'landscape']
in order for Modal to support landscape mode in iOS

      <Modal
        visible={true}
        supportedOrientations={['portrait', 'landscape']}
      >
      </Modal>

All 30 comments

Which version of RN are you running? I tested Modal in RN 0.26.2 with React 15.0.2 and the orientation worked fine.

@sreejithr Pretty sure I saw this on 0.26.x.

The same problem, Modal is not responsive to orientation on RN 0.26.2 on Android system. However, it's perfect on iOS.

@satya164 Sorry, that was a false alarm. It is, indeed, broken in 0.26. I was fooling around in the codebase. So, after a change in orientation to landscape, I followed the execution from UIImplementation.java:updateRootNodeSize() (which gets called because of the setOnSizeChangedListener) to NativeViewHierarchyOptimizer:applyLayoutRecursive().

There, I'm seeing that for the ReactTextShadowNode inside my Modal, getScreenWidth() gives the old width (portrait). I understand that CSSNode:calculateLayout() on the root node updates the layout information. Shouldn't it update the dimensions of this text node as well?

Here's the markup I rendered code:

      <View style={styles.container}>
        <Modal visible={this.state.modalVisible}
         onRequestClose={e => this._setModalVisible(false)}>
          <Text style={{backgroundColor: "red"}}>Inside Modal</Text>
        </Modal>
        <TouchableHighlight
         onPress={e => this.setState({modalVisible: true})}>
          <Text>Show</Text>
        </TouchableHighlight>
      </View>

Sorry for the clarification. I'm new to the codebase. Please do let me know if my assumptions are wrong.

Also, I'd like to work on this issue if it wasn't apparent already :)

Sorry, I'm not very familiar with Modal's code. May be @dmmiller can help.

Modal definitely isn't resizing properly in rotation. I'm aware of that but haven't had a chance to fix it. If @sreejithr wants to look at it, that would be awesome. Unfortunately I'm a little stuck on some other things currently. I will probably get back to Modal stuff next week.

@corysmith and I have also noticed this. We're crunching through a deadline as well but may be able to help out with this.

Any updates on the status of this? I'm still seeing the rotation issue on Android with RN 0.30.

Any updates on this also?

Urgently needed, any updates? Or workarounds anyone???

I finally just gave up and replaced my <Modal /> component with a View with the following style:

<View style={{position: 'absolute',
  flex: 1,
  top: 0,
  right: 0,
  bottom: 0,
  left: 0,
}} />

with a <ScrollView /> inside. This actually works quite nicely for displaying the Modal, and resizes properly upon orientation. However, I had to implement the Android back button functionality manually (using BackAndroid) and the entry animations, for which I used react-motion. Not an ideal solution, but it works.

Depending on what functionality you need, there are also other maintained modal libraries out there, such as react-native-modalbox. I found that just using an absolutely positioned View worked best for what I needed, however, and was a nice simple solution.

@esamelson This is only going to work if you don't have a hierarchy that limits the dimensions of your fake modal view box.

Are we working on this for 32?

Nobody is working on this. Feel free to take this up if you want.

Is this fixed in 0.36?

Looks like it's fixed on master. Close?

Tested on 0.36, android is responsive to orientation, but the orientation issue still exists on iOS

The second bug, modal not being responsive to orientation, exists in iOS as well. Tested it on 0.36 and 0.37

i found that this is not a bug, as shown on the doc Modal section
https://facebook.github.io/react-native/docs/modal.html
we need to set the supportedOrientation prop of the Modal to ['portrait', 'landscape']
in order for Modal to support landscape mode in iOS

      <Modal
        visible={true}
        supportedOrientations={['portrait', 'landscape']}
      >
      </Modal>

Modal is not responsive to orientation, even if the device is in landscape mode, Modal is drawn according to potrait mode, so it kinda covers half the screen and the bottom part gets hidden

I think this is fixed in Android as of 0.37.0.

The bug is still there on Android/RN 0.41.

UPD: It's not. Sorry, my mistake.

@fcFn I just created a new app with react-native init --version="0.41.0" ReactNativeIssue7708, and then implemented a Modal as shown in the docs. Everything seemed to be working fine.

It does work fine. I just wasn't handling the orientation change. Silly me. :sweat:

I used Modal in version 0.40 ad now 0.42 and everything works fine on iOS and android. So I can not reproduce this behavior.

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

this should help https://github.com/facebook/react-native/pull/15102 for the orientations, and a recent crash.

OMG, I just wasted some hours trying to figure out why the incoming dimensions were flipping like mad. Only to find here that I had to add supportedOrientations={['portrait', 'landscape']} to my Modal ??? Why is that not default?

heh i guess it was just overlooked. i hope my pr above will be merged soon.

yah, please :)

Was this page helpful?
0 / 5 - 0 ratings