vincenzopalazzo
vincenzopalazzo

Reputation: 1645

Component modal in react-native doesn't resize correctly when the keyboard appears on IOS

I have a problem is rendering correctly of this modal dialog when the keyboard appear on IOS OS.

I'm a biginner with react-native and the my code looked how the following


App.js

render() {
        return (
            <PaperProvider theme={theme}>
                <StatusBar backgroundColor={theme.colors.primary} barStyle="light-content"/>
                <SafeAreaView style={GlobalStyle.droidSafeAreaTop}/>
                <SafeAreaView style={GlobalStyle.droidSafeAreaDown}>
                    <View>
                        <Appbar.Header style={GlobalStyle.appBar}>
                            <Avatar.Image size={35} source={require('./assets/avatar.png')}/>
                            <Appbar.Content
                                title="LOCAL TIME everywere"
                            />
                            <Appbar.Action icon="refresh" onPress={() => {
                                this.setState({refresh: !this.state.forceRefreshView});
                            }}/>
                        </Appbar.Header>
                        <ScrollViewCardsTime
                            data={this.state.dataSource}
                            onComunicate={this.doCloseSnackBar}
                            onRefresh={this.doRefreshListWithApi}
                            setState={p => {
                                this.setState(p)
                            }}
                            {...this.state}
                        />
                        <DialogNewTimeZone
                            title="New Time Zone"
                            visible={this.state.dialogVisible}
                            setState={p => {
                                this.setState(p)
                            }}
                            {...this.state}
                            onSubmit={this.doAddDataToList}
                            onComunicate={this.doCloseSnackBar}
                        />
                    </View>
                    <FAB
                        style={ComponentStyle.fab}
                        visible={this.state.toastVisible === false}
                        fat
                        label='New Time Zone'
                        icon="plus"
                        onPress={() => this.setState({dialogVisible: true})}
                    />
                    <Snackbar style={{backgroundColor: theme.colors.backgroundSnackBar}}
                              theme={theme}
                              visible={this.state.toastVisible}
                              onDismiss={() => this.doCloseSnackBar(true)}
                              action={{
                                  label: 'close',
                                  onPress: () => {
                                      this.doCloseSnackBar(true)
                                  }
                              }}
                    >
                        {this.state.toastMessage}
                    </Snackbar>
                </SafeAreaView>
            </PaperProvider>
        );

and inside the component DialogNewTimeZone I have this code with the following style

DialogNewTimeZone.component.js


render() {
        return (
            <Modal.BottomModal
                visible={this.props.dialogVisible}
                onTouchOutside={() =>
                    this.props.setState({dialogVisible: false})
                }
                onSwipeOut={() => this.props.setState({dialogVisible: false})}
            >
                <ModalTitle
                    title={this.props.title}
                />
                <ModalContent>
                    <TextInputLayout styles={styles.inputLayout}>
                        <TextInput
                            style={styles.textInput}
                            placeholder={'City name ex: Rome, Phoenix'}
                        />
                    </TextInputLayout>
                    <TextInputLayout styles={styles.inputLayout}>
                        <TextInput
                            style={styles.textInput}
                            placeholder={'Country ex: Europe, America'}
                        />
                    </TextInputLayout>
                    <View style={DialogNewTimeZoneStyle.buttonsDialog}>
                        <Button primary
                                text="Search link"
                                icon={'search'}/>
                    </View>

                </ModalContent>
                <ModalFooter style={DialogNewTimeZoneStyle.textFooter}>
                    <Text>
                        Find your Zone and copy the link inside the
                        "link text"
                    </Text>
                </ModalFooter>
            </Modal.BottomModal>
        );
    }

with this style

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 100
    },
    textInput: {
        fontSize: 16,
        height: 40
    },
    inputLayout: {
        marginTop: 16,
        marginHorizontal: 36
    }
});

But I have different effect when keyboard appear in Android and IOS, the android work well, like this

but on ios the effect is wrong, like:

I'm losing something?

Thanks for your time

Upvotes: 2

Views: 1582

Answers (3)

Raj Shah
Raj Shah

Reputation: 738

import React, { useEffect, useState } from 'react';
import { Dimensions, Keyboard } from 'react-native';
import Modal from 'react-native-modal';
import { SlideAnimation } from 'react-native-modal';

const YourComponent = ({ visible, onClose }) => {
  const [isKeyboardActive, setIsKeyboardActive] = useState(false);

  useEffect(() => {
    const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', _keyboardDidShow);
    const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', _keyboardDidHide);

    return () => {
      keyboardDidShowListener.remove();
      keyboardDidHideListener.remove();
    };
  }, []);

  const _keyboardDidShow = () => {
    setIsKeyboardActive(true);
  };

  const _keyboardDidHide = () => {
    setIsKeyboardActive(false);
  };

  const deviceWidth = Dimensions.get('window').width;

  return (
    <Modal
      visible={visible}
      style={{
        justifyContent: isKeyboardActive ? 'center' : 'flex-end',
      }}
      modalAnimation={
        new SlideAnimation({
          initialValue: 0, // optional
          slideFrom: 'bottom', // optional
          useNativeDriver: true, // optional
        })
      }
      onTouchOutside={() => {
        onClose();
      }}>
      {/* Your modal content goes here */}
    </Modal>
  );
};

export default YourComponent;

Upvotes: 0

Keshav Gera
Keshav Gera

Reputation: 11254

import React, { useState, useEffect, useRef } from 'react';

const inputRef = useRef(null);
  const [isInputFocused, setInputFocused] = useState(false);


useEffect(() => {
    isInputFocused ? inputRef.current.focus() : inputRef.current.blur();
        setTimeout(() => setInputFocused(true), 500);


  }, [isInputFocused]);

    const handleInputFocus = () => setInputFocused(true);
  const handleInputBlur = () => setInputFocused(false);


<Autocomplete
    ref={inputRef}
    onFocus={handleInputFocus}
    onBlur={handleInputBlur}

Upvotes: 0

rahulje9
rahulje9

Reputation: 162

I created a workaround for this, but this is not smooth.

import {Keyboard,...} from 'react-native';
    constructor(props) {
        super(props);
        this.state = {
             isKeyboardActive: false
        };
    }

    componentDidMount() {
        this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
        this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
    }

    componentWillUnmount() {
        this.keyboardDidShowListener.remove();
        this.keyboardDidHideListener.remove();
    }

    _keyboardDidShow = () => {
        this.setState({ isKeyboardActive: true });
    };

    _keyboardDidHide = () => {
        this.setState({ isKeyboardActive: false });
    };

render() {
        const { visible } = this.props;
        const { value, isKeyboardActive } = this.state;

        const deviceWidth = Dimensions.get('window').width;
        return (
            <Modal
                visible={visible}
                style={{
                    justifyContent: isKeyboardActive ? 'center' : 'flex-end'
                }}

                modalAnimation={
                    new SlideAnimation({
                        initialValue: 0, // optional
                        slideFrom: 'bottom', // optional
                        useNativeDriver: true // optional
                    })
                }
                onTouchOutside={() => {
                    this.props.onClose();
                }}>
               //your content
            </Modal>
        );
    }



Upvotes: 1

Related Questions