react-nativereact-native-paperreact-native-modal

Adding a UI element such as a button on fixed position on react native modal


I am having difficulty in placing any UI element with fixed position(float) over a react native modal where modal content exceeds the screen hight. A similar issue happens with flash message/snack bar etc. They are rendered at the top/bottom of the modal content(not visible if you have scrolled) instead of them showing up at the top/bottom of the page. I created an example using FAB of react-native-paper to demonstrate this. Link here - https://snack.expo.io/PnX5RCE1_?

Sample code:

import * as React from 'react';
import { StyleSheet, View, Modal } from 'react-native';
import { FAB } from 'react-native-paper';
import { Container, Header, Body, Title, Content, ListItem, Text, Icon, Right } from 'native-base';

const renderModal = () : React.ReactElement<any> => {
    return(
      <Modal
        animationType="fade"
        visible={true}>
        <Container>
            <Header>
                <Body>
                    <Title>Alert</Title>
                </Body>
                <Right>
                  <Icon name="closecircleo" type="AntDesign"></Icon>
                </Right>
            </Header>
            <Content style={{padding: 10}}>
              <Text>Adding a lot of text to make the modal content go out of screen height</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <FAB
                style={styles.fab}
                small
                icon="plus"
                onPress={() => console.log('Pressed')}
              />
            </Content>
        </Container>
      </Modal>
    );
  }

const MyComponent = () => (
  <View>
    {renderModal()}
  </View>
);

const styles = StyleSheet.create({
  fab: {
    position: 'absolute',
    margin: 16,
    right: 0,
    bottom: 0,
  },
})

export default MyComponent;

Solution

  • As you noted yourself, Content exceeds screen height. Since FAB is it's child, it is positioned relative to the total size of Content, not the size of the screen. You should move the FAB up in your view hierarchy:

    {...}
                <Text>Some Text Here</Text>
              </Content>
              <FAB
                style={styles.fab}
                small
                icon="plus"
                onPress={() => console.log('Pressed')}
              />
            </Container>
    {...}