Search code examples
react-nativereact-native-scrollview

Scrollview scrolls too far down when focusing inputText


[solved] I'm building an app and i have an issue where the scrollview scrolls further up than the input. the goal is to have it below the menu when you have pressed the input field.

Here is my wrapperwithnavbar.js:

import React from 'react';
import Wrapper from './Wrapper'
import Navbar from './Navbar'
import { Platform , Text} from 'react-native';

export default function WrapperWithNavbar(props){
    return (
        <>
        <Navbar/>
        <Wrapper refreshing={props.refreshing} onRefresh={props.onRefresh} innerStyle={props.innerStyle} style={[(Platform.OS == "web" ? {'paddingTop':60} : {'paddingTop':110}),props.style]}>
            {props.children}
        </Wrapper>
        </>
    )
}

Here is my wrapper.js:

import React, { useState, useEffect, useRef } from 'react';
import { ScrollView, View, KeyboardAvoidingView,RefreshControl, SafeAreaView } from 'react-native';
import {styles} from '../assets/styles/components/Wrapper' 

export default function Wrapper(props){

    const [refreshing, setRefreshing] = React.useState(false);
    
    const onRefresh = React.useCallback(() => {
      setRefreshing(true);
      setTimeout(() => {
        setRefreshing(false);
      }, 2000);
    }, []);
 
  
    return (

        <ScrollView
        automaticallyAdjustKeyboardInsets={true}        
        refreshControl={
            <RefreshControl refreshing={props.refreshing ? props.refreshing : false} onRefresh={props.onRefresh} />
        }
        style={[styles.wrapper,props.style]}>

            <View style={[styles.wrapperInner,props.innerStyle]}>
               {props.children}
            </View>
        </ScrollView>
    )
}

here is my page with the inputs (states etc. removed for simplicity):

import React, {useEffect, useState} from 'react';
import { Text, View, Platform } from 'react-native';
import {useNavigation} from '@react-navigation/native';
 
// components
import WrapperWithNavbar from '../../components/WrapperWithNavbar' 
import Header from '../../components/Header'
import Button from '../../components/Button'
import CountSelector from '../../components/CountSelector'
import Input from '../../components/Input'

 

export default function CreateEventCultureplace(props){
 
  
  const navigation = useNavigation();
 
   
  return (
    
    <WrapperWithNavbar type="CULTUREPLACE">

      <Header title="Opret begivenhed"/>

      {/** The input that is clicked and goes "above" the menu */}
      <Input value={event} onChangeText={setEvent} type="text" title="Begivenhed (f.eks. open mic)"/>
      
      <Button onPress={()=>{allowPress && createEvent()}} style={[!allowPress?{backgroundColor:"#ffb38a"}:null,{"marginBottom":50}]} title="Opret begivenhed"/>

      {Platform.OS!="web" && <View style={{"height":100}}></View>}

    </WrapperWithNavbar>
    
  )
}

Here is my input.js:

import React, {useState} from 'react';
import {SafeAreaView, Text, TextInput, Platform} from 'react-native';
import {styles} from '../assets/styles/components/Input'

export default function Input(props) {
    const [isFocused, setIsFocused] = useState(false);
    
    return (
        <SafeAreaView style={[props.style,styles.wrapper]}>
            <Text style={styles.text}>{props.title}</Text>
            <TextInput
                scrollEnabled={false}
                numberOfLines={props.numberOfLines ? props.numberOfLines : undefined}
                multiline={props.multiline===true ? true : false}
                onKeyPress={(props.onKeyPress) && props.onKeyPress}
                onFocus={() => {setIsFocused(true)}}
                onBlur={() => {setIsFocused(false)}}
                autofocus={!props.autofocus ? false : true}
                inputStyle={props.inputStyle}
                style={[styles.input,props.inputStyle, isFocused && !props.readonly ? styles.focused : '', (Platform.OS=='web') && styles.web]}
                value={props.value}
                onChangeText={props.onChangeText}
                placeholder={props.title}
                placeholderTextColor="#777"
                autocomplete={props.autocomplete}
                secureTextEntry={(props.type == "password" ? true : false)}

                editable={props.readonly?false:true}
            />
        </SafeAreaView>
    );
}
 

Solution

  • You should have to remove automaticallyAdjustKeyboardInsets in your scrollview and replace scrollView with KeyboardAwareScrollView which import from react-native-keyboard-aware-scroll-view.

    For more details you can visit react-native-keyboard-aware-scroll-view

    Here is your wrapper.js

    import React, { useState, useEffect, useRef } from 'react';
    import { ScrollView, View, KeyboardAvoidingView,RefreshControl, SafeAreaView } from 'react-native';
    import {styles} from '../assets/styles/components/Wrapper' 
    import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
    
    export default function Wrapper(props){
    
        const [refreshing, setRefreshing] = React.useState(false);
    
        const onRefresh = React.useCallback(() => {
          setRefreshing(true);
          setTimeout(() => {
            setRefreshing(false);
          }, 2000);
        }, []);
    
    
        return (
    
          <KeyboardAwareScrollView
            keyboardShouldPersistTaps={'handled'}
    
            refreshControl={
                <RefreshControl refreshing={props.refreshing ? props.refreshing : false} onRefresh={props.onRefresh} />
            }
            style={[styles.wrapper,props.style]}>
    
                <View style={[styles.wrapperInner,props.innerStyle]}>
                   {props.children}
                </View>
          </KeyboardAwareScrollView>
        )
    }