react-native
react-native copied to clipboard
Android - Modal with `statusBarTranslucent` has wrong height
Description
On the old architecture, when using a Modal
with no animation and translucent status bar, a layout flash is noticeable when the modal is opened. Here's the video of this happening (it's visible for one frame):
https://user-images.githubusercontent.com/21055725/211768547-d3ff49b9-2ce6-4f36-9f0f-91ad102fab28.mov
On the new architecture, the issue is more problematic as the modal keeps the wrong height:
https://user-images.githubusercontent.com/21055725/211768801-df57b295-fa04-4bd8-af35-0057553bf15b.mov
I believe the problem may be with this line as the windowFullscreen
will be true only when the relevant property is set on the app's theme, and not when the View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
flag is set on view (which is the case here).
The flash on the old arch comes from the fact that the height is updated here to the correct value. This is also the case for the new arch, however, the correct values get overwritten with every state update.
This also happens on 0.71.0-rc.6.
Simply removing the state updates here and here, which I've done in https://github.com/facebook/react-native/pull/35803, seems to be solving the problem (at the cost of the modal appearing one frame later), however, I'm not that familiar with the code so it may have some unintended consequences.
Version
0.70.5
Output of npx react-native info
System:
OS: macOS 12.6
CPU: (8) arm64 Apple M1 Pro
Memory: 100.31 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
Watchman: 2022.10.24.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /opt/homebrew/lib/ruby/gems/3.0.0/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0
Android SDK:
API Levels: 24, 26, 28, 29, 30, 31, 32, 33
Build Tools: 26.0.3, 28.0.3, 29.0.2, 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0, 33.0.0
System Images: android-28 | Google ARM64-V8a Play ARM 64 v8a, android-32 | Google APIs ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9123335
Xcode: 14.0.1/14A400 - /usr/bin/xcodebuild
Languages:
Java: 11.0.14 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.5 => 0.70.5
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Steps to reproduce
Create a Modal
with animationType="none"
and statusBarTranslucent={true}
and open it.
Snack, code example, screenshot, or link to a repository
import React, {useState} from 'react';
import {View, Button, Modal} from 'react-native';
const App = () => {
const [open, setOpen] = useState(false);
return (
<View style={{flex: 1, backgroundColor: 'yellow'}}>
<Button
title="Open"
onPress={() => {
setOpen(true);
}}
/>
<Modal
visible={open}
animationType="none"
statusBarTranslucent={true}>
<View style={{flex: 1, backgroundColor: 'red'}}>
<Button
title="Close"
onPress={() => {
setOpen(false);
}}
/>
</View>
</Modal>
</View>
);
};
export default App;
The same issue. For me, the previous view has a layout flash when the TextInput
on Modal
is focused. It can always reproduce when I init a new project on React Native 0.71.0
.
The react-native info
:
➜ TestRN npx react-native info
info Fetching system and libraries information...
System:
OS: macOS 12.5
CPU: (8) arm64 Apple M2
Memory: 97.84 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 19.1.0 - /opt/homebrew/bin/node
Yarn: Not Found
npm: 8.19.3 - /opt/homebrew/bin/npm
Watchman: 2022.11.28.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
Android SDK: Not Found
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9123335
Xcode: 14.2/14C18 - /usr/bin/xcodebuild
Languages:
Java: 11.0.17 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: 0.71.0 => 0.71.0
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
the code snippets as follows:
import React, { Component } from "react";
import {
View,
Modal,
Dimensions,
TextInput,
TouchableOpacity,
Text
} from "react-native";
const { height } = Dimensions.get("window");
class App extends Component {
constructor(props) {
super(props);
this.state = {
visible: false
};
}
render() {
return <View style={{ flex: 1, backgroundColor: "white" }}>
<View style={{ height: height - 250 }} />
<TouchableOpacity onPress={() => {
this.setState({ visible: true });
setTimeout(() => {
this.setState({ visible: false });
}, 5000);
}} style={{ alignSelf: "center", backgroundColor: "blue", width: 250, height: 60 }}>
<Text style={{ marginLeft: 50, color: "red", fontSize: 30 }}>Show modal</Text>
</TouchableOpacity>
<Modal visible={this.state.visible} statusBarTranslucent={false}>
<View style={{ flex: 1, backgroundColor: "white" }}>
<TextInput style={{ height: 60, backgroundColor: "green", margin: 80 }} />
</View>
</Modal>
</View>;
}
}
export default App;
You can see the component Show modal
(with blue
background color) has a fast flush when TextInput
is focused while the keyboard is popped up. It works normal if I set statusBarTranslucent={true}
, but I don't want the status bar is covered by the modal.
the video demo(gif):
https://user-images.githubusercontent.com/22851821/215783516-46d4684a-ff2e-4e18-8b23-17958bd7dd56.mov
This is still an issue in react-native 0.71.7. I'm getting the impression that the Modal has a number of issues surrounding animations in the new architecture, since there's also an issue with callbacks not firing when the Modal has a slide animation (I'm pretty sure now that issue I filed has nothing to do with NativeBase).
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This is still an issue
I can confirm the problem. Modal height is less by the height of status bar than it should be.
Still an issue in RN 0.73.3
I have the same issue. In my case, both the status bar and the navigation bar are hidden, and it looks like ModalHostHelper
only takes into account the height of the status bar.
The behavior potentially depends on the Android version. As per documentation, Display.getSize
returns:
API level 29 and below — The size of the entire display (based on current rotation) minus system decoration areas is returned.
API level 30 and above — The size of the top running activity in the current process is returned. If the current process has no running activities, the size of the device default display, including system decoration areas, is returned
cc @j-piasecki to please cross check if this still happens on 0.74
~~It seems to be working correctly in 0.74, although it has a visible blink~~ I checked the old arch 🤦♂️
It's still a problem, here's the code from the issue running on RNTester:
https://github.com/facebook/react-native/assets/21055725/7f4589b0-52dc-4e62-9814-71f19f422aa8
cc @cortinico
0.74.2 new arch +1