React-native: TextInput inside View doesn't work

Created on 25 Feb 2015  路  18Comments  路  Source: facebook/react-native

<View>
  <TextInput placeholder="This works" />
  <View>
    <TextInput placeholder="This doesn't work" />
  </View>
</View>

The sample project with this bug is here - https://github.com/boopathi/textinputbug

Am I doing something wrong here ?

Locked

Most helpful comment

For people looking here for a solution, without understanding/going through someone's code:

Specify a height to the TextInput seemed to fix the problem of it not working.

Example:

<View>
    <View>
        <TextInput
            style={styles.input}
            onChangeText={(text) => this.setState({ input: text })}
            placeholder="Input Here"
        />
    </View>
</View>
const styles= StyleSheet.create({
    input: {
        height: 20, //comment this out and TextInput wont work (some cases the grey background wont be there)
        width: 100,
        background: 'grey, //added for visual
    },
});

All 18 comments

This is a known bug, if you change your css to something like:

  container: {
    flex: 1,
    top: 50,
    borderWidth: 1,
    borderColor: 'blue',
  },
  subc: {
    borderWidth: 1,
    borderColor: 'red',
  },

You'll see that your TextInput is out of the Veiw bounds, so you can't touch it.

If I understand this correctly, React Native is doing the right thing here.

top, I assume, is measured relative to the parent element. So in https://github.com/boopathi/textinputbug/blob/5cc5eb455dcb8d5843451cf9b93ea6720d9439c7/index.ios.js#L19 it ends up with top: 100 and top: 150. Both of which will be well outside their parent element.

I haven't used css-layout before. If child is relative to the parent element and there is no height specified to parent, does the parent element expand when top is specified to child or the child goes out of the parent element ?

But, looks like it does come out of the parent container. I did a test with css-layout - https://github.com/boopathi/textinputbug/blob/master/css-style.js - and the result I got was this https://github.com/boopathi/textinputbug/blob/master/css-style.output.json . The height of the child is used to compute parent's height, but the child top is not considered to compute parent's height.

So, I guess the fix for this would be to not style(top, etc...) the textinputs and manually add height to parent.

I'm not sure, in plain css it wouldn't work, because you didn't set a position value and you're use top... If you set the position than it will be positioned out of the parent, just as css-layout.

The thing is that, in the HTML, even if you use position and leave the child of the parent, you can still touch it... What has to be decided is what is the desired behavior.

/cc @nicklockwood that's the behavior I was trying to explain to you not so long ago.

So, I guess the fix for this would be to not style(top, etc...) the textinputs and manually add height to parent.

Seems likely it'd work by putting the top on the containing views instead of the inputs themselves.

The thing is that, in the HTML, even if you use position and leave the child of the parent, you can still touch it... What has to be decided is what is the desired behavior.

Yeah the combination of it being visible but untouchable sucks :( Maybe views should clip to bounds by default?

The thing is that, in the HTML, even if you use position and leave the child of the parent, you can still touch it... What has to be decided is what is the desired behavior.

This is the way iOS works and definitely feels wrong. I'd really like it to be fixed but I'm unsure if it's even possible. Would love some iOS experts to chime in

@vjeux If we really want to make it work we're going to have to reimplement hitTest...
but if you don't have to hit the parent to hit the child, we'll basically have to search all views...

So interestingly the work's already been done to support this. RCTView will hit test its subviews regardless of whether they're in its bounds iff pointerEvents is box-none: https://github.com/facebook/react-native/blob/f3cd27cf483671b8821e4f50bfa7bb370893e59a/React/Views/RCTView.m#L126-136

And indeed, if we use the original example in https://github.com/boopathi/textinputbug/blob/326362e5d39588682048bccda281d6bb2701d04a/index.ios.js with pointerEvents='box-none' on the problem parent views, it works as expected :boom:

So making this "just work" seems to only be a matter of changing the default pointerEvents, or changing the behavior of RCTPointerEventsUnspecified to fallback to searching its subviews.

@joshaber Interesting... I hadn't seem it there lol

Maybe for RCTPointerEventsUnspecified we could use basically the same, but instead of returning nil if it doesn't match any subview we return [super hitTest:withEvent:]

Yup, I think that makes sense :+1:

@joshaber That works. Thanks!

@tadeuzagallo :+1: auto can use this, so there is less confusion.

Should the TextInput be working in iOS now? I am on 0.18.1 and TextInput is not visible on iOS, while working as expected on Android

@latusaki that sounds like a different issue. The original reporter was complaining that a <TextInput> inside a <View> that was smaller than it couldn't receive touch events, not that the <TextInput> was invisible.

Can you provide an example demonstrating the problem that you're seeing?

I have made a question on SO about this, http://stackoverflow.com/questions/35086827/reactnative-textinput-not-visible-ios, there I was told that TextInput is not visible on IOS when lineHeight or width is not set. If I set them it is visible. Is this the expected behaviour ?

Hmm, I'm not sure what the correct behavior should be, but it definitely shouldn't be different between platforms. @dmmiller, do you know which platform is behaving incorrectly here?

@nicklockwood I think it should show on iOS. It probably ought to use defaults (like the line height of the font). It does show on Android and on the web with an tag without any size or style information.

For people looking here for a solution, without understanding/going through someone's code:

Specify a height to the TextInput seemed to fix the problem of it not working.

Example:

<View>
    <View>
        <TextInput
            style={styles.input}
            onChangeText={(text) => this.setState({ input: text })}
            placeholder="Input Here"
        />
    </View>
</View>
const styles= StyleSheet.create({
    input: {
        height: 20, //comment this out and TextInput wont work (some cases the grey background wont be there)
        width: 100,
        background: 'grey, //added for visual
    },
});

I dont see the input text neither the border of the input box ?
my inputstyle is as follows:
inputStyle:{height:40,borderColor:"green",borderWidth:1}

Was this page helpful?
0 / 5 - 0 ratings