Giter Club home page Giter Club logo

react-native-spacer's Introduction

React Native Spacer

NPM badge NPM badge

A view wrapper that will float above the keyboard when it displayed

Technically, it uses Animated.View and will animate a translateY value to avoid the keyboard. KeyboardAvodingView is highly recommended. But in some rare case when KeyboardAvodingView not working, try this Spacer.

Demo

See demo on Expo Snack

Demo

I. Installation

npm install --save react-native-spacer

II. How to use

Class Spacer is a wrapper using Animated.View. For usage, see official documentation Animated and View

1. Import library

import Spacer from 'react-native-spacer';

2. Wrap component into Spacer

<Spacer spaceMargin={20}>
    {/* Components that need to float when keyboard showing */}
</Spacer>

III. Properties

Property Name Type Default Value Definition
spaceMargin number 0 Component's margin above the keyboard when it displayed
enabled bool true Set to false to disable Spacer
backgroundColor string #fffffff7 Spacer component background color
animationDuration number 300 Duration of the view animation

Feel free to have any question, file an issue, or contributing to the module.

IV. Todo

  • Create tests

V. Changes

  • v1.7.0: Fix measureInWindow not found for latest RN version (thanks @kristerkari)

react-native-spacer's People

Contributors

hieunc229 avatar idanbo avatar jmmendivil avatar kristerkari avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-native-spacer's Issues

Remove spaceMargin prop

Hey,
Just came across this code and I can see great use cases for it. (Like when trying to use a KeyboardAvoidingView inside a component that displays a react-navigation TabNavigator.)

Just looking at the code, we can clean it up by removing the spaceMargin prop and let the user handle that with margin on their own component being rendered inside Spacer.

Android showing lots of spaces in bottom

Thank you for this awesome library, but when on android, it is creating lots of spaces below.. see the image plz. Also plz resolve this notice if possible:

EventEmitter.removeListener('keyboardWillHide', ...): Method has been deprecated. Please instead use remove()on the subscription returned byEventEmitter.addListener.

Screenshot_1639066450

License?

Hello,
Thanks a lot for the great helper. It solves a massive problem in a very decent way.

Can you please add a license file to the repo, clarifying what people can and cannot do with the library?

Thanks again.

Cheers,

Sometimes first iOS key press acts like keyboard hide

Brief

When using the component as a wrapper for whole app, sometimes the first iOS key press ever acts like the keyboard is hidden. It runs the animation that hides stuff behind the keyboard.

Closing the keyboard later and opening it again would work just fine until I restart the app.

I did not try in Android.

Below I'll mention what seemed to fix it for me.

Details

I was playing with the sample app from react-native-size-matters. It had a chat window with textbox at the bottom that suffered from the keyboard issue.

After some messing up to upgrade the sample itself to react-native 0.55 (latest expo supports), and running it, and trying KeyboardAvoidingView then finding facebook/react-native#13393 (comment), I modified the file that wraps all components:

https://github.com/nirsky/react-native-size-matters/blob/16383ea10bafcfd508cfbafb36995f4ea27b7f2a/examples/expo-example-app/components/behaviors/withScaledSheetSwitch.js#L9

Which originally looked like:

https://github.com/nirsky/react-native-size-matters/blob/16383ea10bafcfd508cfbafb36995f4ea27b7f2a/examples/expo-example-app/components/behaviors/withScaledSheetSwitch.js#L9-L17

    render() {
        return <View style={{flex: 1}}>
            <View style={{alignSelf: 'stretch', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', margin: 10}}>
                <Text style={{fontSize: 16}}>size-matters enabled?</Text>
            <Switch value={this.state.scale} onValueChange={() => this.setState(prevState => ({scale: !prevState.scale}))}/>
            </View>
            <ChildComponent {...this.props} scale={this.state.scale}/>
        </View>
    }

To now look like:

            return (
                <Spacer enabled style={{ height: '100%' }}>
                    <View  style={{flex:1, height: '100%'}}>
                            <View style={{ alignSelf: 'stretch', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', margin: 10 }}>
                                <Text style={{ fontSize: 16 }}>size-matters enabled?</Text>
                                <Switch value={this.state.scale} onValueChange={() => this.setState(prevState => ({ scale: !prevState.scale }))} />
                            </View>
                            <ChildComponent {...this.props} scale={this.state.scale} />
                    </View>
                </Spacer>
            );
        }

(I only added the <Spacer> and styled it, and gave the <View> under it height: '100%')

To imagine the app (pic from iPad, but I experienced the issue on most recent iPhone simulator, with iOS 12):

image

Then when I opened the chat page in the app, I click on the textbox at the bottom, and the keyboard popped up with the screen shifting above it nicely, but when I clicked on the keyboard to enter text, the view expanded to full window, hiding the textbox behind the keyboard.

I clicked away, then clicked the textbox again, and tried typing. This time the textbox stayed higher than the keyboard. It worked just fine from then onwards. I reloaded the app and tried again, and oops, it failed the first time, but then it worked just fine the following times.

I repeated the test several times, disabled the scaling from react-native-size-matters to make sure it's not affecting anything, but same result. First key press on phone keyboard would expand the view behind the keyboard, but after hiding and showing the keyboard, pressing keys doesn't cause any harm.

Investigation

I looked at the source code of the Spacer library, which was super awesome BTW, simplicity is great, and not easy, and I was able to fix the above problem by changing a few methods:

    _keyboardWillShow = ev => {
        if (this.props.enabled) {
            // Calculation new position above the keyboard
            let toValue = (this._locationY + this._viewHeight) - (windowHeight - (ev.endCoordinates.height + this._spaceMargin));
            this._animate(-1 * toValue).start();
        }
    };
    _setLayoutProps = ev => {
        this._container
                ._component
                .measureInWindow((x, y, width, height) => {
                    this._locationY = y;
                    this._viewHeight = height;
                })
    };

Both changes seemed to be needed. The first change in _keyboardWillShow removes the dependency on this._container in calculations. I'm not sure if this can be a problem sometimes (when the component is not outermost), which is part of the reason why I'm not creating a PR for this yet.

The other change felt more straightforward, and almost opposite the first one. It updates this._viewHeight based on the this._container._component.measureInWindow().

Extras

I also added a componentWillUnmount, but just because it felt right, not because of this issue.
It looked like:

    componentWillUnmount() {
        Keyboard.removeListener(showListenerEvent, this._keyboardWillShow);
        Keyboard.removeListener(hideListenerEvent, this._keyboardWillHide);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.