◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/App Dev
◇ App Dev/2026-07-05Intermediate

Building a One-Time Code Field in Expo — SMS Autofill and Segmented Display Together

A six-digit verification screen looks trivial, but once you account for SMS autofill, pasting, and deleting one digit at a time, it needs real care. Here is how to nail the iOS and Android autofill first, then build a segmented look on top of a single TextInput that does not break.

Rork585Expo219React Native239Authentication8UX Design9

✦ Premium Article

When I added phone verification to one of my apps, my first attempt was the obvious one: six TextInputs sitting side by side. It looked tidy, but the feedback arrived fast. "The code from the SMS never shows up above the keyboard." "When I paste, only the first box fills in." The moment I split the field into boxes, I had quietly broken both iOS autofill and clipboard paste. As an indie developer shipping several apps to the App Store, this one screen — the verification code field — is something I have rebuilt more times than I would like to admit.

A code entry screen sits right before sign-up or payment, exactly where you least want people to drop off. A single moment of friction here loses someone who was already interested. Let me walk through building an input in Expo (React Native) where SMS autofill, pasting, and deleting all feel natural.

Splitting into boxes cuts off autofill

The first snag in a code field is the mismatch between how it looks and how input actually works. Visually you want each digit in its own box. But OS autofill treats one field as the target and tries to drop the whole six-digit string into it.

Split that into six TextInputs and iOS cannot decide which field to inject into, so the keyboard suggestion (the code chip) never appears at all. Android's SMS autofill assumes a single field too. Paste lands only in the one focused box.

That leads to a single guiding principle: split the appearance, keep the input as one. Place a single transparent TextInput, then draw its value one character at a time so it reads as a row of boxes.

Set the autofill attributes first

Lock down autofill before anything else. Leave it for later and you will build the whole UI, then lose an afternoon to "why is the suggestion not showing." The required attributes differ by OS.

GoaliOSAndroid
Code autofilltextContentType="oneTimeCode"autoComplete="sms-otp"
Keyboard typekeyboardType="number-pad" (for numeric codes)
Suppress autocorrectautoCorrect={false}; let textContentType take priority

One caution: copying an importantForAutofill value from an old blog post can actually make Android ignore sms-otp. Start from the minimal setup above and add attributes only when you truly need them.

import { TextInput } from "react-native";
 
// The single real input. It stays transparent because the boxes are drawn separately
<TextInput
  value={code}
  onChangeText={handleChange}
  keyboardType="number-pad"
  textContentType="oneTimeCode" // iOS: surfaces the SMS code as a suggestion
  autoComplete="sms-otp"        // Android: SMS autofill
  maxLength={6}
  autoFocus
  style={{ position: "absolute", opacity: 0 }}
/>
✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦The correct way to make iOS textContentType=oneTimeCode and Android autoComplete=sms-otp both fire
✦The pattern of looking like six boxes while actually being one TextInput, so autofill and paste keep working
✦Key handling that survives both a full six-digit paste and deleting one character at a time
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◇ App Dev2026-08-16
My chart broke on day one, not at scale
A line chart that vanished for anyone with only a few days of data. The cause was a zero-height Y axis turning coordinates into NaN. Here is the measured behavior and the small normalization layer that fixed it.
◇ App Dev2026-08-06
Deciding overlay text legibility at ingest time instead of on device — four metrics measured side by side
Moving the question of whether text stays readable over a wallpaper out of the device and into the content pipeline. Four candidate metrics measured across 240 images, including what downscaled judging actually computes.
◇ App Dev2026-10-15
When adjustsFontSizeToFit Shrinks Just One Row, Suspect the Box Height, Not the String
Only the 10th row of a list drops to 4pt on iOS, though the data and strings are fine. I read the Yoga rounding and font-fit sources, then counted how often the box comes up short in Node.