Skip to content

Conversation

@DimitrisTzimikas
Copy link

@DimitrisTzimikas DimitrisTzimikas commented Feb 9, 2026

Summary

When navigating away from a screen containing swipeable rows and then navigating back, the native view detaches (onDetachedFromWindow on Android / willMove(toSuperview: nil) on iOS) which unregisters the view from the static viewRegistry. Upon reattach, the recyclingKey prop setter short-circuits (if (oldValue == value) return) because the value hasn't changed, so the view is never re-registered.

This causes all closeByKey() / closeAll() calls to silently fail — getView(key) returns null because the registry entry was removed on detach and never restored.

Fix

  • Android: Added onAttachedToWindow() override that re-registers the view via registerView(this, recyclingKey)
  • iOS: Added re-registration in the existing didMoveToWindow() when window != nil via Self.registerView(self, for: key)

How to reproduce (before fix)

  1. Render a list with <Swipeable> rows (e.g. a room list)
  2. Swipe a row open, press an action button → row closes correctly
  3. Navigate to another screen and come back
  4. Swipe a row open, press an action button → row stays open (stuck)

After the fix, step 4 works correctly the row closes immediately on button press.

When navigating away and back, the native view detaches
(unregistering from viewRegistry via onDetachedFromWindow/willMove)
and reattaches, but the recyclingKey prop setter short-circuits
because the value hasn't changed. This leaves the view unregistered,
causing all closeByKey/closeAll calls to silently fail.

Adds re-registration in onAttachedToWindow (Android) and
didMoveToWindow (iOS) so the view is always findable in the
static registry after reattach.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant