Vertically center a ScrollView

Viewed 77

I have a ScrollView that I would like to vertically center. There are two requirements: when the ScrollView is small (one text line), that line should be in the center of screen. When the ScrollView is large (exceeds the screen size), it should function as a normal ScrollView. I can seemingly only get one or the other to work.

<SafeAreaView style={{flex: 1}}>
   <Pressable style={flex: 1, justifyContent: 'center'}>
      <Pressable>
         <ScrollView />
      </Pressable>
   </Pressable>
</SafeAreaView>
3 Answers

You can apply alignSelf property to ScrollView parent to center itself. Here is a Snack for same.

<SafeAreaView style={{flex: 1}}>
   <Pressable style={{flex: 1, justifyContent: 'center'}}>
      <Pressable  style={{
            height: '100%',
            width: '60%',
            alignSelf : 'center'
          }}>
         <ScrollView />
      </Pressable>
   </Pressable>
</SafeAreaView>

Your ScrollView needs to have a fixed height.

const CenteredScrollView = (props) => {
  // random text to render
  let randomText = [
    "Just some random stuff, ya know? Hopefully this manages to reach the point that it exceeds the screen size, ya know ? ",
    "Read on brother of another mother. ",
    "Read on sister of another mister. ",
    "Some words here. Hopefully this manages to reach the point that it exceeds the screen size, ya know ? ",
    "Some words there. Hopefully this manages to reach the point that it exceeds the screen size, ya know ? ",
    "Some words where? Hopefully this manages to reach the point that it exceeds the screen size, ya know ? ",
    "I really dont know what but some stuff has just happened. ",
    "How much text do I need to fill the screen size? ",
    ]
    // simulate ScrollView exceeding screen height
    for( let i = 0; i<5;i++)
      randomText = randomText.concat(randomText.reverse())
  return(
    <SafeAreaView style={{flex: 1 }}>
      <Pressable style={{flex: 1, justifyContent:'center', backgroundColor:'green' }}>
        <Pressable>
          <ScrollView
           {/*important to give ScrollView a height*/}  
           style={{backgroundColor:'pink',height:'50%'}}
          >
            {randomText.map((text,i)=><Text key={i}>{text}</Text>)}
          </ScrollView>
        </Pressable>
      </Pressable>
    </SafeAreaView>
  );
}

I was able to achieve this with the following:

const content = useMemo(() => <View onLayout={({nativeEvent}) => setContentHeight(nativeEvent.layout.height)}>{insert_anything}</View>, [insert_anything])

return <View onLayout={({nativeEvent}) => setParentHeight(nativeEvent.layout.height)}>
    {
        contentHeight >= parentHeight ?
        <ScrollView>{content}</ScrollView} :
        content
    }
</View>
Related