Skip to content

lxcid/ReactNativeBug-NestedViewInTextInput

Repository files navigation

ReactNativeBug-NestedViewInTextInput

There were a few similar issues before this one that got closed by the bot (facebook/react-native#17467 & facebook/react-native#17468) because it's missing information or went stale. The author open a stack overflow question that did not get answer.

Here's my attempt to provide a more complete argument and be as informative as possible to help push this feature request/bug fix forward.

I'm aware that <TextInput /> uses SpannableString in Android and NSAttributedString in iOS underneath, both are capable of inlining image (Android with ImageSpan and iOS with NSTextAttachment). But this is not supported by React Native as of v0.54.2.

To be specific, I'm talking about <Image /> nested within <Text /> nested within <TextInput multiline />.

One of the use case is to support custom emoji as described by @just4fun in facebook/react-native#17468 in the GIF below:

Custom Emoji

Environment

Environment:
  OS: macOS High Sierra 10.13.3
  Node: 9.2.0
  Yarn: 1.3.2
  npm: 5.5.1
  Watchman: 4.9.0
  Xcode: Xcode 9.2 Build version 9C40b
  Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
  react: ^16.3.0-alpha.1 => 16.3.0-alpha.3
  react-native: 0.54.2 => 0.54.2

Steps to Reproduce

A react native project have been created at lxcid/ReactNativeBug-NestedViewInTextInput. You can pull it down locally and launch the project with react-native run-ios or react-native run-android.

Expected Behavior

At minimum, I would hope for <TextInput> + <Text> + <Image> to work as expected in iOS and Android. For example:

<TextInput multiline>
  <Text style={styles.text}>
    There is a react logo{' '}
    <Image
      source={images.react}
      style={{ width: 30, height: 30, backgroundColor: 'pink' }}
    />{' '}
    in between my text.
  </Text>
</TextInput>
// Copied from https://github.com/lxcid/ReactNativeBug-NestedViewInTextInput/blob/1afdd2383ac70d08edc7c4742321cc46c5af225b/app/screens/TextInputImageScreen.js#L14-L23

But if we are able to support <TextInput> + <Text> + <View> as well, that would be awesome!

Actual Behavior

Text + Image

First of all, <Text /> do support nested images, even though its not well documented. There might be some rendering differences between iOS and Android, but they are generally supported.

Text + Image

Text + View

As for nested views in <Text />, only iOS is supported. This is documented here.

Text + View

TextInput + Image

Surprisingly, for <Image /> nested within <Text /> nested within <TextInput />, It worked for Android but not so much for iOS, which did not display the image.

TextInput + Image

TextInput + View

As for nested views in <TextInput />, Android crashes while iOS does not display the image.

TextInput + View

Summary

I create a table to summarize and compare what we have observed here:

Components Android iOS
<Text> + <Image>
<Text> + <View> 💥
<TextInput> + <Text> + <Image>
<TextInput> +<Text> + <View> 💥

References