Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyboardAvoidingView has no effect on multiline TextInput #16826

Open
peacechen opened this issue Nov 14, 2017 · 114 comments
Open

KeyboardAvoidingView has no effect on multiline TextInput #16826

peacechen opened this issue Nov 14, 2017 · 114 comments
Labels
Bug Component: TextInput Related to the TextInput component. Platform: iOS iOS applications. Ran Commands One of our bots successfully processed a command.

Comments

@peacechen
Copy link

KeyboardAvoidingView only works with single-line TextInputs. When the multiline prop is set, KeyboardAvoidingView does not shift the TextInput at all.

Is this a bug report?

Yes

Have you read the Contributing Guidelines?

Yes

Environment

Environment:
OS: macOS Sierra 10.12.6
Node: 7.0.0
npm: 3.10.8
Watchman: 4.7.0
Xcode: 9.1

Packages: (wanted => installed)
react-native: 0.49.3
react: 16.0.0-beta.5

Target Platform: iOS (10.3)

Steps to Reproduce

  1. Use a <TextInput> component with multiline prop set.
  2. Wrap this in a ScrollView
  3. Wrap that in a KeyboardAvoidingView.

Expected Behavior

Multiline TextInput should scroll above the soft keyboard.

Actual Behavior

Soft keyboard covers multiline TextInput.

Reproducible Demo

import React, { Component } from 'react';
import { Text, TextInput, View, ScrollView, KeyboardAvoidingView, Keyboard} from 'react-native';

...

	render() {
		return (
			<KeyboardAvoidingView style={{flex:1}} behavior="padding" keyboardVerticalOffset={64}>
				<ScrollView keyboardShouldPersistTaps={'handled'}>
					<View style={{padding: 12}}>
						// various content to fill the page
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 1</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 2</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 3</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 4</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 5</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 6</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 7</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 8</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 9</Text>
						<Text style={{fontSize: 20, padding: 40}}>MESSAGE 10</Text>
					</View>
					<TextInput
						style={{padding: 4}}
						multiline={true}
						placeholder={'Type something here...'}
						onChangeText={this.updateMessage}
						value={this.state.message}
					/>
				</ScrollView>
			</KeyboardAvoidingView>
		);
	}

@vivalaakam
Copy link

vivalaakam commented Nov 15, 2017

I have a similar issue

Environment

node: 8.9.1
react: 16.0.0
react-native: 0.50.3
yarn: 1.3.2
watchman: 4.9.0
xcode: 9.1

Steps to Reproduce

  1. Use a <TextInput> component with autoCorrect="false" prop.
  2. Wrap that in a KeyboardAvoidingView with behavior="position" prop.
  3. Change keyboard type to Emoji keyboard

Expected Behavior

Multiline TextInput should be above the soft keyboard.

Actual Behavior

Soft keyboard covers TextInput.

Reproducible Demo

https://github.com/vivalaakam/react-native-issue

@vivalaakam
Copy link

Keyboard.addListener('keyboardWillChangeFrame', this.onKeyboardChange) doesn't`t fire when I change keyboard to emoji and fires when I change from emoji to other

@jibberilins
Copy link

KeyboardAvoidingView works fine with multiline TextInput because i am using them myself. Initially they would not work for me. To solve my problem i removed the height on the TextInput and set the behavior to "padding". The "flex: 1" you have on the KeyboardAvoidingView might be the problem i think or its the scrollview. But KeyboardAvoidingView definitely works fine with multiline.

@peacechen
Copy link
Author

peacechen commented Nov 27, 2017

Referring to my snippet posted above, there's no height on the TextInput, and KeyboardAvoidingView's behavior is set to padding.

Its style needs flex:1 to allow the ScrollView to take up the entire height.

Try the code with and without multiline set. It fails with multiline set, but the same code works for single line TextInputs.

@hoscarcito
Copy link

Same problem here!

@react-native-bot react-native-bot added Ran Commands One of our bots successfully processed a command. Component: TextInput Related to the TextInput component. labels Mar 16, 2018
@fadlykayo
Copy link

@peacechen I have exactly the same problem like you. Need to add flex: 1 for the ScrollView as the wrapper. And it works if I remove the prop multiline={true}. Any solution for this?

@sherxia92
Copy link

sherxia92 commented May 10, 2018

The same issue。
my code is same as the author. there is a multiline TextInput in ScrollView. outsider with a KeyboardAvoidingView wrapper.

@monmonja
Copy link

monmonja commented May 18, 2018

If anyone still is looking for a fix, you could try

<View style={{position:relative}}>
    <TextInput ref='multilineText' value={this.state.textValue} 
        onChangeText={(textValue) => this.setState({textValue})}/>
    <TextInput style={{ color:'transparent', position: 'absolute', width: '100%', height: '100%' }}
        placeholderTextColor='transparent'
        onFocus={() => setTimeout(() => this.refs.multilineText.focus(), 1000) } 
        value={this.state.textValue}
        onChangeText={(textValue) => this.setState({textValue})}
    />
</View>

Its a dirty hack but it does the job, what it does it when user clicks on the input it would be clicking on the single line and the keyboard will scroll to that line then after 1 seconds (you can adjust this, i just found 1 seconds to be good with our app) it would focus on the multiline. The value and onChangeText makes sure that when the user star typing they would have the same value except the single line has transparent text.

The downside is when a user clicked the multiple line, the cursor wont go to the location they clicked but it would go to the end.

@peacechen
Copy link
Author

peacechen commented May 18, 2018

@monmonja That's a creative work-around. I wonder if it could also be done by setting the multiline prop to a state variable that is changed during onFocus. That would eliminate the second TextInput.

I don't see the multiline prop in the first TextInput, but I assume it's supposed to be in there.

@kfroemming-cb
Copy link

Has anyone found a good solution for this?

@chmielot
Copy link

chmielot commented Jul 2, 2018

@peacechen I tried to implement your suggestion but it has a strange effect and doesn't work. Something's flickering and the keyboard eventually disappears.
I am also looking for a solution to this. Cannot apply @monmonja 's workaround because I'm using redux-form. This makes it much more complicated for this workaround.
I can confirm that all is working fine when I remove the multiline prop. I wrapped the whole application with KeyboardAvoidingView and my multiline TextInput is at the end of the form like in the author's example. I have no height applied to the TextInput which in a few cases can cause issues.
I am using react-native: 0.53.0

@Hsuer
Copy link

Hsuer commented Jul 9, 2018

same problem here and still have no solution

@sndkd
Copy link

sndkd commented Aug 1, 2018

I too facing the same issue. It works fine if multiline is set to false and not if set to true. My TextInput does not have any height. Any solutions??

@jasonchoibiz
Copy link

jasonchoibiz commented Aug 17, 2018

A workaround for this is to make a reference to the parent scrollview and call its scrollTo method to the multilined TextInput coordinates whenever onFocus is called.

<KeyboardAvoidingView
   style={{ flex: 1 }}
   behavior="padding"
>
  <ScrollView ref={component => { this.myScrollView = component; }}>
    <TextInput 
       multiline
       onFocus={() => this.myScrollView.scrollTo({ x: 0, y: 750, animated: true })} // <- your coordinates here
    />
  </ScrollView>
</KeyboardAvoidingView>

@lucasboleli
Copy link

same problem here only on IOS
textinput multiline has no effect on keyboardavoidingview

it is working fine on android

@amsul
Copy link

amsul commented Aug 24, 2018

This has been quite frustrating for us as well.. Seems like the only consistent way to do this is by scrolling manually as @jasonchoibiz suggested.

It's an ugly workaround though! ☹️

@robertobrogi
Copy link

there is news about this problem?

@luco
Copy link

luco commented Sep 27, 2018

Still having this. Tried the suggested solutions.

@mitevdev
Copy link

mitevdev commented Oct 1, 2018

same problem here

@Jmedders
Copy link

Jmedders commented Oct 1, 2018

Same issue, here's a simple snack for anyone to play with: https://snack.expo.io/r1qpj0k5Q

@mitevdev
Copy link

mitevdev commented Oct 2, 2018

Same issue, here's a simple snack for anyone to play with: https://snack.expo.io/r1qpj0k5Q

I've tried this and it works:

https://github.com/baijunjie/react-native-input-scroll-view

@linoleum00
Copy link

react-native version 0.56.1
same problem....

@recepkoseoglu
Copy link

it is working;

<KeyboardAvoidingView behavior="padding" style={Platform.OS !== 'android' && { flex: 1 }}> 
  <ScrollView>
      ... 
      <TextInput ... />
      ...
  </ScrollView>
</KeyboardAvoidingView>

@luco
Copy link

luco commented Nov 13, 2018

@recepkoseoglu It works on non-multiline Inputs. Try on multiline.

@karimelsaidy
Copy link

karimelsaidy commented Jun 13, 2023

5 years and no direct solution yet?!

@MoFerhat
Copy link

MoFerhat commented Jun 21, 2023

Damn it's June 2023 and the only "solution" is scrollEnabled={false} ? stop a bit...

@mathbalduino
Copy link

I think FB has bigger concerns right now lol

@alainib
Copy link

alainib commented Jun 22, 2023

2023 and not a proper way to avoid keyboard over input from reactnative ....

@ahmetares
Copy link

july 2023...

@jbagaresgaray
Copy link

Bump

@honcon
Copy link

honcon commented Jul 23, 2023

Hi folks,

After a lot of search I've a workaround for my case, The thing I wanted was not have a scrollable TextInput but a non-scrollable infinite height as size of text as gives and this view contained to a ScrollView working properly with a KeyboardAvoidingView,

Voila:

import React, { useState } from 'react';
import { SafeAreaView, ScrollView, TextInput, View, KeyboardAvoidingView, Keyboard, TouchableWithoutFeedback } from 'react-native';

import { Header } from 'react-native/Libraries/NewAppScreen';

export default function App(): JSX.Element {
  const [text, setText] = useState(`
  One
  Two
  Three
  Four
  Five`);

  const [textInputHeight, setTextInputHeight] = useState(40);

  const handleTextChange = (newText: any) => {
    setText(newText);
  };

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>

          <ScrollView
            style={{
              backgroundColor: '#00ffff32',
              borderWidth: 1,
              borderColor: '#0000ff',
            }}
          >
            <Header />
            <View style={{}}>
              <TextInput
                style={{
                  borderWidth: 1,
                  height: Math.max(40, text.split('\n').length * 20),
                }}
                onChangeText={handleTextChange}
                value={text}

                onContentSizeChange={event => {
                  const { height } = event.nativeEvent.contentSize;
                  setTextInputHeight(Math.max(40, height));

                }}
                multiline={true}
                scrollEnabled={false}
              />
            </View>
          </ScrollView>
        </TouchableWithoutFeedback>
      </KeyboardAvoidingView>

    </SafeAreaView>
  );
}

I wrapped this functionality in a CustomInputView component of course

@istvan-panczel
Copy link

istvan-panczel commented Jul 24, 2023

Hi,

I'm new to React-Native and ran into the same problem.
I came up with a dirty hack for myself, probably can help out someone else in the future:

const [isScrollEnabledForTextArea, setIsScrollEnabledForTextArea] = useState<boolean>(false);

<TextArea
  keyboardType={'default'}
  isInvalid={invalid}
  value={value}
  onChangeText={onChange}
  onBlur={() => {
    setIsScrollEnabledForTextArea(false);
  }}
  autoCompleteType={'off'}
  autoCapitalize={'none'}
  autoCorrect={false}
  scrollEnabled={isScrollEnabledForTextArea}
  onFocus={() => {
    // dirty hack, the KeyboardAvoidingView cant handle an input if it has multiline text
    setTimeout(() => setIsScrollEnabledForTextArea(true), SEC_IN_MS);
  }}
></TextArea>

I'm using NativeBase with <Controller /> and <TextArea /> but the problem is the very same. This solved it for me.

@Shelrothman
Copy link

So setting scrollEnabled to false made the KeyboardAvoidingView logic work for me.. yay.
BUT... now... my clearButtonMode prop doesn't work! Ack! Anyone else got to this point?
Thank you community for your help.

@Shelrothman
Copy link

For anyone still looking for a solution to this. I created an NPM package, expo-clear-input that is a solution to the above by working on any platform (web, ios, android) and in both single and multiline <TextInput>s.

A little x button for all

@Jonathan0wh
Copy link

It is 2024 now... Still no direct fix?

@joshenx
Copy link

joshenx commented Jan 23, 2024

fix?

@TaewookKwak
Copy link

TaewookKwak commented Jan 25, 2024

Key Down
스크린샷 2024-01-25 오후 11 47 23

Key Up
스크린샷 2024-01-25 오후 11 53 18

return code

return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : undefined}
      enabled
      style={styles.avoid}
      keyboardVerticalOffset={0}>
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.input}
          editable
          multiline
          textAlignVertical="top"
          onChangeText={newText => setText(newText)}
          value={text}
          maxLength={maxLength}
          autoFocus={true}
        />
        <View style={styles.counterContainer}>
          <Text style={styles.counter}>{`${text.length}/${maxLength}`}</Text>
        </View>
        <DotButton style={{width: '100%'}}>
          <DotButton.ButtonText>Send</DotButton.ButtonText>
        </DotButton>
      </View>
    </KeyboardAvoidingView>
  );

style

 inputContainer: {
    maxHeight: 500,
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    marginHorizontal: 20,
  },
  input: {
    flex: 1,
    borderWidth: 1,
    borderColor: '#000',
    borderRadius: 10,
    alignSelf: 'stretch',
  },
  counterContainer: {
    alignSelf: 'stretch',
  },
  counter: {
    textAlign: 'right',
    marginTop: 4,
  },
  avoid: {
    flex: 1,
  },

for those who have a similar structure as me

@fabOnReact
Copy link
Contributor

fabOnReact commented Feb 2, 2024

I believe it is an issue with RCTScrollViewComponentView.mm and/or RCTUITextView.

The behaviour is not automatic on iOS, some libs provide it like IQKeyboardManager.

I tested the workaround from comment-1148477911 (branch).

My understanding is that the native iOS implementation of ScrollView will keep the current scroll position automatically, for example:

  1. ScrollView displays item 1-10
  2. ScrollView height is resized from 700 to 300
  3. After resizing, the ScrollView will scroll down so that item 10 is still visible at the bottom. The scroll position does not change

step 3) does not work on iOS when using multiline TextInput (UITextView), while it works when using single line TextInput (UITextField). Probably, the fact that UITextView can scroll, breaks this functionality.

Maybe the iOS implementation of UITextView/ScrollView keeps the position constant based on the contentOffset, but as we have 2 scrollviews (ScrollView scrolls and UITextView scrolls), the implementation manages the content offset of the TextInput multiline, instead of the parent scrollview.

KeyboardAvoidingView just wraps a view with style={{padding: bottom}} and decreases the height of the native ScrollView by the height of the keyboard

case 'position':
return (
<View
ref={this.viewRef}
style={style}
onLayout={this._onLayout}
{...props}>
<View
style={StyleSheet.compose(contentContainerStyle, {
bottom: bottomHeight,
})}>
{children}
</View>
</View>
);

as you can see, there is no native impl of KeyboardAvoidingView, simply it changes the ScrollView height

CLICK TO OPEN TESTS RESULTS

Screenshot 2024-02-02 at 11 56 15 AM

after opening the keyboard, the scrollview height is decreased by the height of the keyboard, but the scrollview fails to scroll to the previous position

CLICK TO OPEN TESTS RESULTS

Screenshot 2024-02-02 at 11 58 53 AM

I also added to the below example, logic to scroll down the scrollview after opening the keyboard.

  • It works when scrolling up
  • It does not work when scrolling down
CLICK TO OPEN TESTS RESULTS

import * as React from 'react';
import {
  Keyboard,
  StyleSheet,
  KeyboardAvoidingView,
  ScrollView,
  View,
  Text,
  TextInput,
} from 'react-native';

const RNTesterApp = () => {
  const [text, setText] = React.useState(
    'a line 1 \n a line 2 \n a line 3 \n a line 4 \n a line 5 \n a line 6 \n a line 7 \n',
  );
  let scrollViewRef = React.useRef(null);
  const [isScrollEnabled, setIsScrollEnabled] = React.useState(true);

  const onKeyboardWillShow = () => {
    console.log('onKeyboardWillShow');
    setIsScrollEnabled(false);
    if (scrollViewRef) {
      console.log('scrollToEnd');
      scrollViewRef.scrollTo({x: 0, y: 300});
    }
  };

  function onKeyboardDidShow() {
    console.log('onKeyboardDidShow');
    setIsScrollEnabled(true);
  }

  React.useEffect(() => {
    const subKWS = Keyboard.addListener('keyboardWillShow', onKeyboardWillShow);
    const subKDS = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);

    return () => {
      subKWS.remove();
      subKDS.remove();
    };
  }, []);

  return (
    <KeyboardAvoidingView style={{flex: 1, marginTop: 100}} behavior="padding">
      <ScrollView
        ref={ref => (scrollViewRef = ref)}
        keyboardShouldPersistTaps={'handled'}
        maintainVisibleContentPosition={{minIndexForVisible: 1}}>
        <View style={{padding: 12}}>
          <Text style={styles.text}>MESSAGE 1</Text>
          <Text style={styles.text}>MESSAGE 2</Text>
          <Text style={styles.text}>MESSAGE 3</Text>
          <Text style={styles.text}>MESSAGE 4</Text>
          <Text style={styles.text}>MESSAGE 5</Text>
          <Text style={styles.text}>MESSAGE 6</Text>
          <Text style={styles.text}>MESSAGE 7</Text>
          <Text style={styles.text}>MESSAGE 8</Text>
          <Text style={styles.text}>MESSAGE 9</Text>
          <Text style={styles.text}>MESSAGE 10</Text>
          <Text style={styles.text}>MESSAGE 11</Text>
        </View>
        <TextInput
          multiline={true}
          placeholder={'Type something here...'}
          onChangeText={setText}
          value={text}
          scrollEnabled={true}
          style={styles.input}
        />
      </ScrollView>
    </KeyboardAvoidingView>
  );
};

export default RNTesterApp;

const styles = StyleSheet.create({
  text: {
    fontSize: 20,
    padding: 40,
  },
  input: {
    height: 50,
  },
});

I may consider working on this issue and publishing a fix if requested by the community.
I believe it requires an extensive implementation in UITextView and RCTScrollViewComponentView to control their content offset.

https://github.com/hackiftekhar/IQKeyboardManager/blob/aa656e1f0d95f0154622f453599318602848be3b/IQKeyboardManager/IQKeyboardManager.m#L838-L853

https://stackoverflow.com/a/20052756/7295772

https://stackoverflow.com/a/69811662/7295772

Similar issues, but on Android are #25239 and #30373 (comment)

@vanenshi
Copy link

vanenshi commented Feb 3, 2024

@fabOnReact Thanks for the great details on the problem, Fabrizio
this is a 7-year-old problem, if you manage to fix it, all of us can remove the nasty workaround in our code and start using the pure component.

@fabOnReact
Copy link
Contributor

Thanks, but I decided to not contribute anymore to facebook/react-native.

@Paraschoudhary176
Copy link

Paraschoudhary176 commented Mar 4, 2024

`<KeyboardAvoidingView
style={{ flex: 1 }}
behavior="padding"

<ScrollView ref={component => { this.myScrollView = component; }}>
<TextInput
multiline
onFocus={() => this.myScrollView.scrollTo({ x: 0, y: 750, animated: true })}
/>

`

This is how this will work. You can also try keyboard aware scroll view , or in android manifiest.xml can change the adjust keyboard. or if nothing works then we have antother alternative a prop called tabBarHideOnKeyboard: true.

@pein892
Copy link

pein892 commented Mar 7, 2024

@Paraschoudhary176 Thanks for your thoughts, and here is my solution:

const App = () => {
  const scrollViewRef = useRef(null)
  const textInputRef = useRef(null)

  const onFocus = () => {
    if (Platform.OS === 'ios') {
      if (scrollViewRef.current && textInputRef.current) {
        textInputRef.current.measureLayout(
          scrollViewRef.current,
          (x, y, width, height) => {
            setTimeout(() => {
              scrollViewRef.current.scrollTo({y: y, animated: true});
            }, 500);  // 500ms just work fine.
          },
          () => {},
        );
      }
    }
  }

  return (
    <KeyboardAvoidingView>
      <ScrollView ref={scrollViewRef}>
        <TextInput 
          ref={textInputRef} 
          multiline={true} 
          numberOfLines={3} 
          onFocus={onFocus} />
      </ScrollView>
    </KeyboardAvoidingView>
  )
}

@kirillzyusko
Copy link
Contributor

kirillzyusko commented Jun 20, 2024

Hello, maintainer and creator of react-native-keyboard-controller is here 👋

I think KeyboardAwareScrollView from react-native-keyboard-controller should solve this problem - it automatically detects a moment when focused TextInput is growing and automatically scrolling to the necessary coordinates.

Theoretically similar behavior can be backported to KeyboardAvoidingView component from RNKC because this functionality is powered by another hook (layout changes detection) - but I hardly can imagine a layout where KeyboardAvoidingView+multiline is more preferable option over KeyboardAwareScrollView+multiline.

Anyway, if you have such examples and if you think, that something is not working or should work in a different way - feel free to open issues in react-native-keyboard-controller repository 👀

@Energieman
Copy link

Energieman commented Jul 18, 2024

in 2024, Here is my working fix, scrollEnabled={false} did most of the magic. I honestly hope it helps someone here.

<KeyboardAwareScrollView
enableAutomaticScroll={true}
innerRef = {(ref) => setScrollViewRef(ref)}
style={{backgroundColor: 'green'}}>
<TextInput
scrollEnabled={false} //2
ref={editFieldRef}
editable={noteEditable}
placeholder="Enter note..."
placeholdercolor={BaseColor.blackColor}
onChangeText={text => {setNoteText(text);}} //avoidGoingBack();
value={noteText}
defaultValue={noteText}
multiline = {true}
numberOfLines = {10}
autoFocus={true}
forcedStyle={{fontSize: 20}} //custom TextInput component prop
style={{
minHeight: '100%', //for ios because number of lines dosent work with it
color: BaseColor.unchangeableClack, backgroundColor: colorPaleteToUse,
}}
/>

@alainib
Copy link

alainib commented Jul 19, 2024

in 2024, Here is mu working fix, scrollEnabled={false} did most o the magic. I honestly hope it helps someone here.

<KeyboardAwareScrollView enableAutomaticScroll={true} innerRef = {(ref) => setScrollViewRef(ref)} style={{backgroundColor: 'green'}}> <TextInput scrollEnabled={false} //2 ref={editFieldRef} editable={noteEditable} placeholder="Enter note..." placeholdercolor={BaseColor.blackColor} onChangeText={text => {setNoteText(text);}} //avoidGoingBack(); value={noteText} defaultValue={noteText} multiline = {true} numberOfLines = {10} autoFocus={true} forcedStyle={{fontSize: 20}} //custom TextInput component prop style={{ minHeight: '100%', //for ios because number of lines dosent work with it color: BaseColor.unchangeableClack, backgroundColor: colorPaleteToUse, }} />

disabling scroll on a scrollview .... not a fix at all , if you have like 10 inpunt inside to show ? (

@shuo-hiwintech
Copy link

+1

@chrisdev3001
Copy link

chrisdev3001 commented Jul 28, 2024

I dont wanna depends on another library for this bug, here is my solution:

Custom hook:

import { useRef } from 'react'
// import { doSomethingAtSecondX } from '@core/utils'

interface DoSomethingAtSecondX {
  callback: () => void
  seconds: number
}

export const doSomethingAtSecondX = (params: DoSomethingAtSecondX) => {
  const { callback, seconds } = params
  setTimeout(callback, seconds * 1000)
}

interface MoveScrollTo {
  x: number
  y: number
}

export const useMoveScroll = () => {
  const scrollRef = useRef() as any

  const moveScrollTo = ({ x, y }: MoveScrollTo) =>
    scrollRef.current.scrollTo({ x, y, animated: true })

  const moveScrollToDown = (pxToDown: number) => {
    if (scrollRef.current) {
      doSomethingAtSecondX({
        callback: () => moveScrollTo({ x: 0, y: pxToDown }),
        seconds: 0.35
      })
    }
  }

  return {
    scrollRef,
    moveScrollToDown
  }
}

Component:

const { scrollRef, moveScrollToDown } = useMoveScroll()

return (
  <ScrollView
      ref={scrollRef}
      showsVerticalScrollIndicator={false}
      ....
  />

      <Input
        multiline
        numberOfLines={5}
        placeholder='write comments here...'
        onFocus={() => moveScrollToDown(450)}
        onChangeText={setComments}
      />

  </ScrollView>

)

Hope this help 🐰

@aman-technyx
Copy link

@chrisdev3001 can you tell me where i can get this "doSomethingAtSecondX"
import { doSomethingAtSecondX } from '@core/utils'

@HemalSPatel
Copy link

+1

@chrisdev3001
Copy link

@chrisdev3001 can you tell me where i can get this "doSomethingAtSecondX" import { doSomethingAtSecondX } from '@core/utils'

I have updated the code... it was just a little helper function 👀

@ftaibi
Copy link

ftaibi commented Sep 8, 2024

why is so hard to work with keyboards in rn???? :(((((

@aman-technyx
Copy link

@ftaibi this code works for me !

`import React from 'react';
import {
Platform,
Keyboard,
TouchableWithoutFeedback,
ViewStyle,
} from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';

interface Props {
children: React.ReactNode;
style?: ViewStyle;
}

const KeyboardAvoidingComponent: React.FC = ({ children, style }) => {
return (
<KeyboardAwareScrollView
showsVerticalScrollIndicator={false}
style={style}
extraHeight={Platform.OS === 'ios' ? 150 : 0} // adjust height for iOS
enableOnAndroid={true}>

{children}


);
};

export default KeyboardAvoidingComponent;
`

use as

<KeyboardAvoidingComponent style={{flex: 1}}>
. // no need to use scrollview here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Component: TextInput Related to the TextInput component. Platform: iOS iOS applications. Ran Commands One of our bots successfully processed a command.
Projects
None yet
Development

No branches or pull requests