◉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-14Intermediate

Long-Press Context Menus for a Gallery Item in a Rork Expo App

Long-pressing a wallpaper card does nothing, yet iOS users expect a preview and a menu. From why Pressable alone falls short, to a native context menu with zeego, resolving the scroll-vs-long-press conflict, wiring up save and share, and a custom overlay fallback for Android — all with working code.

Rork585Expo219React Native239context menuwallpaper app22

✦ Premium Article

I was scrolling a wallpaper gallery on a real device and, almost absentmindedly, long-pressed a card. Nothing happened. Anyone used to an iPhone has muscle memory from the Photos app and the home screen: press and hold, and a preview with a menu should appear. Answering that expectation with silence makes the whole app feel a notch cheaper. Working on wallpaper apps as an indie developer, I have watched this small friction quietly cost engagement more than once.

The list screens Rork generates usually wrap a Pressable with nothing but a tap-to-navigate handler. Let us start there and work out why the long-press menu, specifically, needs one extra step.

What onLongPress leaves on the table

Pressable ships with onLongPress, so detecting the gesture itself is trivial.

<Pressable onPress={openDetail} onLongPress={() => setMenuOpen(true)}>
  <Image source={item.uri} style={styles.card} />
</Pressable>

But all this can raise is a sheet or modal you drew yourself. It is not the experience iOS shows by default — the target lifting gently, the background blurring, the preview appearing before you even release your finger. That lift and blur come from UIContextMenuInteraction, a native mechanism you cannot fully reproduce by stacking views from JavaScript.

So the decision comes down to this. If matching the behavior iOS users already know is the priority, bridge to a native context menu. If you want full control over the animation or a unified look on Android, build your own around onLongPress. For a wallpaper app that only needs the familiar trio of save, share, and favorite, the native route wins on both experience and effort.

Decide between two approaches first

Before writing anything, here is the trade-off on one page.

ConcernNative context menu (zeego)Custom overlay (Reanimated)
iOS preview liftExactly as standardClose, but hard to match fully
Consistent Android lookFollows the Material popupFully yours to design
Implementation effortLowHigh (gestures and geometry)
Dynamic menu itemsSomewhat constrainedFlexible

For the gallery I wanted the iOS feel out of the box, so I built with zeego first and only pulled the pieces I cared about on Android into a custom path. zeego is a thin wrapper over the native context menu, and it falls back to a regular menu where the native one is unavailable. When in doubt, I would start from zeego.

✦

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
✦Why Pressable's onLongPress alone never gives you the iOS preview-and-menu experience, and where the line is
✦Building a native context menu with zeego and resolving the scroll-vs-long-press conflict via delayLongPress
✦Bundling save, share, and favorite into one menu, and switching to a custom overlay on Android
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.