Skip to content
This repository has been archived by the owner on Jul 27, 2021. It is now read-only.

input-scroll-view and wrapper #38

Closed
luco opened this issue Aug 14, 2018 · 7 comments
Closed

input-scroll-view and wrapper #38

luco opened this issue Aug 14, 2018 · 7 comments

Comments

@luco
Copy link
Contributor

luco commented Aug 14, 2018

Hey,

I'm trying to render my input-scroll-view in this way:

<View style={{flex: 1}}>
{currentCart.length ? (
                <InputScrollView style={{flex: 1}}>
               ...

But this doesn't work properly. It gives me this error:
image

It only works when I wrap the entire view with the input-scroll-view. But this doesn't let me to center align another view.

Thoughts?

Thanks

@baijunjie
Copy link
Owner

It seems that the parent element of the InputScrollView cannot be {flex: 1}

I don't see the problem from this picture?
I see that your application uses a single line of input, and it's above the window, why use this plugin?

@luco
Copy link
Contributor Author

luco commented Sep 27, 2018

No, they're not. These inputs sits on bottom of page, which I should scroll to reach. When trying to focus on them, the Scrollview pushes them to top like this.

@baijunjie
Copy link
Owner

It seems that InputScrollView needs to be kept away from { flex: 1 }. This will cause the scrollResponderScrollNativeHandleToKeyboard() to not work properly.

  • { flex: 1 } cannot be used on the InputScrollView.
  • { flex: 1 } cannot be used on the InputScrollView's parent node.

@mitevdev
Copy link

mitevdev commented Oct 2, 2018

Hi baijunjie,

my TextInput components are embedded and the code in _cloneDeepComponents does not recognize properly the multiline property and it does not set the multiline handler, because it is set internally of course:

class Parent extends Component {
state = {}
...
render() {
return(
<TextInput multiline .... />
);
}
}

This can be solved in the following way - a dedicated custom method is invoked in Component (when provided of course) so the wrapper is given the chance to return the TextInput component to your logic for further handliche. This method could. be called getTextInputComponent() in example.

I will try to implement it and will give you feedback on success.

UPDATE: I do not think I can access component's custom method from within children opaque data structure provided with this.props.children :(

UPDATE: I've managed it to work, just had to proxying these three methods from parent to the embedded TextInput component:

onChange={this.props.onChange}
onContentSizeChange={this.props.onContentSizeChange}
onSelectionChange={this.props.onSelectionChange}

and set multiline on the parent as well.

~cheers

@baijunjie
Copy link
Owner

@bobozee If this method works and is tested, welcome to submit Pull requests. 👍

@mitevdev
Copy link

mitevdev commented Oct 5, 2018

My first idea is not possible because React.Children provides so called opaque data structure for the child element and NOT the component itself so we are not able to access components methods at all.

What I've done is to proxying the methods your solution needs to work in this way:

class TextComponent extends PureComponent {

    state = {
        text: ""
    }

    render() {
        const { component } = this.props;
        return (
            <View style={{
                ...
            }}>                
                ...
                <TextInput     
                    style={{
                        ...
                    }}                     
                    onChange={this.props.onChange}
                    onContentSizeChange={this.props.onContentSizeChange}
                    onSelectionChange={this.props.onSelectionChange}
                    multiline
                    clearButtonMode={"always"}                    
                    maxLength={maxLength} 
                    value={this.state.text}                    
                    placeholder={Strings.components.text.placeHolder}
                    placeholderTextColor={Colors.Gray}
                    onChangeText={(text) => this.setState({
                        text: text
                    })}
                />
            </View>
        );
    }
}

Notice the following lines:

onChange={this.props.onChange}
onContentSizeChange={this.props.onContentSizeChange}
onSelectionChange={this.props.onSelectionChange}
multiline

I've replaced the not relevant parts with "..." so my TextInput components inside your InputScrollView have own states preventing the parent to redraw on every single key press. The use of my class later looks like:

render() {
   const componentsArray = components.map((component, index) => {
            switch (component.type) {
                case "text": return <TextComponent multiline key={index} component={component} />;
                 ...
                 ...
                default:
                    console.error("unknown component type :" + component.type);
            }
    });
   return (
       <InputScrollView style={{                                        
           ...
       }}>                    
            {componentsArray} // array of TextComponents

       </InputScrollView>  
   );
}

and it's done.

@baijunjie
Copy link
Owner

The question we are discussing seems to have nothing to do with this issue, you can reopen an issue.

@luco luco closed this as completed Nov 14, 2018
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants