skip to content

In a React Native grocery checkout, what changes when the delivery-instructions TextInput is multiline, and what differs between iOS and Android?

level: middleimportance: should knowfreq 38%

answer

  1. a different native view on iOS
  2. return inserts a newline by default
  3. Android centres text vertically
  4. grows with content until maxHeight
  5. secureTextEntry is off the table

basics

~20 s

With multiline, return inserts a newline instead of submitting (submitBehavior defaults to 'newline'), the field grows with its content unless a height bounds it, and text sits at the top on iOS but centred on Android until you set textAlignVertical: 'top'.

solid answer

~40 s

`multiline` defaults to `false`; turning it on swaps the native view on iOS from a single-line text field to a multi-line text view. Four things change. Return inserts a newline, because `submitBehavior` defaults to `'newline'` for multiline inputs, so `onSubmitEditing` does not fire unless you set `'submit'` or `'blurAndSubmit'`. The field measures its wrapped text, so without a fixed `height` it grows line by line; bound it with `minHeight` and `maxHeight`, after which it scrolls, and `onContentSizeChange` reports the content size. Alignment differs: iOS puts text at the top, Android centres it vertically, so set `textAlignVertical: 'top'` for both. And `secureTextEntry` does not work with `multiline`. Because return no longer closes the keyboard, the screen needs another way to dismiss it.

code

tsx · 24 lines
tsx
import {StyleSheet, TextInput} from 'react-native';

export function DeliveryNotes({value, onChange}: {value: string; onChange: (t: string) => void}) {
  return (
    <TextInput
      multiline
      value={value}
      onChangeText={onChange}
      maxLength={280}
      placeholder="Delivery instructions (gate code, where to leave it)"
      style={styles.notes}
    />
  );
}

const styles = StyleSheet.create({
  notes: {
    minHeight: 72,
    maxHeight: 160,
    padding: 12,
    borderWidth: 1,
    textAlignVertical: 'top', // Android centres multiline text otherwise
  },
});

go deeper

for a junior

Recall that multiline makes return insert a newline and that Android needs textAlignVertical: 'top' to match iOS.

for a middle

Explain submitBehavior's multiline default, how the field grows with content between minHeight and maxHeight, and which props stop working with multiline.

for a senior

Design a notes field that stays usable on both platforms, bounds its growth inside a long form, and still gives users a clear way to finish editing.

for a principal

Decide which free-text inputs the checkout really needs, balancing courier usefulness against form length and the keyboard handling each multiline field adds.

## Why multiline is more than a flag A delivery-instructions field ("leave with the concierge, ring twice, the gate code is on the intercom") needs several lines. Setting `multiline` on a `TextInput` does more than allow wrapping: - On **iOS**, React Native renders a different native component: a single-line text field becomes a multi-line **text view**. - On **Android**, the same edit text is configured for multiple lines. The default is `multiline={false}`. Once it is on, keyboard behaviour, sizing and alignment all change. ## The return key inserts a newline `submitBehavior` controls what return does. Its default depends on the field: | Field | Default `submitBehavior` | Return key | |---|---|---| | single-line | `'blurAndSubmit'` | fires `onSubmitEditing`, then blurs | | multiline | `'newline'` | inserts a line break | So in a multiline notes field, **`onSubmitEditing` does not fire** by default, and return never closes the keyboard. That is usually right for notes. If the field should submit on return instead, set `submitBehavior="submit"` (keeps focus) or `'blurAndSubmit'` (dismisses). `returnKeyType` still only changes the key's label. Because return no longer dismisses the keyboard, the screen needs another route out: a **Done** control, a tap outside the field, or scrolling away. Keyboard dismissal and avoidance are their own topic, but a multiline field is where the need first shows up. ## Sizing: the field grows with its text A multiline `TextInput` measures its wrapped text within the width it is given. Without a fixed `height`, it therefore **grows by a line** each time the user's text wraps. 1. Give it a `minHeight` so an empty field looks like a notes box, not a single line. 2. Give it a `maxHeight` so a long note does not push the rest of the form off screen. 3. Beyond `maxHeight` the content scrolls inside the field. On iOS `scrollEnabled` (default `true`, multiline only) can turn that scrolling off. 4. `onContentSizeChange`, called only for multiline inputs, reports `nativeEvent.contentSize` with `width` and `height` if you need to react to growth, such as a character-count layout. A single-line input, by contrast, measures its text without wrapping and scrolls horizontally. ## Alignment differs by platform The documentation calls this out: a multiline field **aligns text to the top on iOS and centres it vertically on Android**. With a `minHeight` of several lines, Android users would see their first line floating in the middle of the box. Setting the text style **`textAlignVertical: 'top'`** gives the same top alignment on both platforms. ## Props that do not combine with multiline - **`secureTextEntry`** does not work with `multiline={true}`; masking is a single-line feature. - **`maxLength`** still works and is the right way to cap a note's length natively. - **Autofill hints** rarely apply to free text; leave them unset. ## Common mistakes - **Expecting `onSubmitEditing` to fire** in a multiline field without changing `submitBehavior`; the handler silently never runs. - **Fixing the height** to one value; long notes then scroll inside a small box instead of growing to a comfortable size. - **Testing only on iOS**; the vertically centred text on Android is usually reported by QA, not caught in development. - **Leaving no way out** of the keyboard; users on a small phone cannot reach the **Place order** button under it. - **Trimming or rewriting the note on every keystroke**; cap its length with `maxLength` and trim whitespace once, when the order is submitted. ## A checklist for the notes field - `multiline` on, `submitBehavior` left at `'newline'`; - `minHeight` of about three lines and a `maxHeight` cap; - `textAlignVertical: 'top'` for Android; - `maxLength` matching what the courier's app can display; - a visible way to finish editing, since return adds lines.

  • In React Native, how do you make a multiline TextInput submit on return instead of inserting a newline?
    Set `submitBehavior` explicitly. `'submit'` fires `onSubmitEditing` and keeps focus; `'blurAndSubmit'` fires it and then blurs the field, dismissing the keyboard. Left unset, a multiline field uses `'newline'`, so return only adds a line break and `onSubmitEditing` never fires.
  • In React Native, why does a multiline TextInput with a fixed height of 120 look different on Android than on iOS?
    The docs note that multiline text is aligned to the top on iOS but centred vertically on Android, so with extra space the Android text floats in the middle of the box. Adding `textAlignVertical: 'top'` to the style gives top alignment on both platforms.

saying these in an interview costs you the question

  • A multiline TextInput still submits on return by default.
  • Multiline text is top-aligned on both platforms without extra styling.
  • A multiline TextInput always needs a fixed height or it collapses to one line.
  • secureTextEntry can mask a multiline notes field.
  • returnKeyType="done" makes a multiline field dismiss the keyboard on return.