Custom TopBar button (react component) never resizes to content width under Fabric on iOS 26 and resets to 44pt after any button rebuild

Abierto
#8,339 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Tranquilo
Stack tecnológico
objective-c, react-native
Área
mobile

Línea de trabajo

Comienza con RCTFabricSurface.mm y compara el manejo del tamaño intrínseco con RCTSurface.mm; después, sigue la ruta del delegate a través de RNNReactButtonView.mm. Lee RNNUIBarButtonItem.mm y RNNButtonsPresenter.setButtons: para seguir la creación de constraints y la reconstrucción de los botones. Se considera terminado cuando las anchuras determinadas por el contenido funcionan en Fabric, se actualizan cuando cambia el contenido y permanecen estables después de volver a aplicar TopBar repetidamente.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

platform: iOS type: accepted/bug
What happened?

On iOS 26 with the TopBar (RNNReactButtonView/RNNUIBarButtonItem's initWithCustomView: code path, gated behind if (@available(iOS 26.0, *))), a custom React component used as a topBar.rightButtons[].component never grows past the reserved 44pt minimum slot, even though the button is clearly designed to support it (see the kMinBarButtonSlotSize / "grow width once when React reports intrinsic size" comments in RNNUIBarButtonItem.mm and RNNReactButtonView.mm).

Image

Tracked this down to two separate, compounding bugs in the current implementation:

  1. The width-growth mechanism never fires under Fabric (New Architecture).
    The whole feature depends on -surface:didChangeIntrinsicSize: being called on RNNReactButtonView's delegate. That callback is only ever invoked by the legacy, non-Fabric RCTSurface (see RCTSurface.mm, setIntrinsicSize: → [delegate surface:self didChangeIntrinsicSize:...], driven by rootShadowView:didChangeIntrinsicSize:). Under the New Architecture, RCTFabricSurface declares the same intrinsicSize property (inherited from RCTSurfaceProtocol) but never sets it and never calls the delegate method at all — there is no matching code path in RCTFabricSurface.mm. As a result, RNNReactButtonView.intrinsicSize/measuredSurfaceContentSize is always {0,0} and the button's width constraint is never updated from its initial 44pt value, regardless of how wide the mounted React content actually is.

  2. Even after working around (1), the button snaps back to 44pt the next time TopBar buttons are rebuilt (e.g. reselecting a bottom tab, or any mergeOptions/appear-triggered re-application of topBar.rightButtons). RNNButtonsPresenter.setButtons: calls RNNButtonBuilder.build: → initWithCustomView: and constructs a brand new RNNUIBarButtonItem every time buttons are applied, even though the underlying RNNReactButtonView (looked up via RNNReactComponentRegistry.createComponentIfNotExists:) is reused (it's keyed by componentId in a map and only replaced/removed when actually different). initWithCustomView: unconditionally creates new UILayoutPriorityRequired width/height constraints on that reused view every single time, without ever deactivating the constraints created by the previous RNNUIBarButtonItem instance. This leaves multiple conflicting required-priority width constraints active on the same view (e.g. one pinned at the previously-grown width, a fresh one reset to 44pt) — Auto Layout can't satisfy both, and in practice the newly-added 44pt constraint wins, visibly snapping the button back down.

What was the expected behaviour?

A custom React component used as a TopBar button should size itself to its actual rendered content width (bounded below by the ~44pt minimum tap-target size), and should keep tracking that width correctly:

  • On initial mount, based on the component's real rendered content, not just the reserved 44pt placeholder.
  • On subsequent content changes within the same mounted component (e.g. a counter/badge whose text gets longer or shorter).
  • Consistently across repeated TopBar button re-applications (e.g. switching bottom tabs away and back), without the width getting reset or fighting with stale constraints from a previous RNNUIBarButtonItem instance.
Was it tested on latest react-native-navigation?
  • I have tested this issue on the latest react-native-navigation release and it still reproduces.
Help us reproduce this issue!

Reproduction steps

  1. Clone this public minimal reproduction repo:
    https://github.com/matyi/RNNGlassRepro

  2. Run the app and open the screen that uses a custom React component in topBar.rightButtons.

  3. Observe that the button renders variable-width content, but its width stays constrained and the content gets clipped instead of expanding to fit.

  4. As a workaround, manually measure the mounted view hierarchy and pass the actual size through handleIntrinsicSizeChange:. With that fallback in place, the button grows correctly on first mount.

  5. Put the screen inside a bottomTabs layout.

  6. Let the button grow, then switch to another tab and back, or trigger any flow that causes topBar.rightButtons to be re-applied, such as a mergeOptions call in componentDidAppear.

  7. Observe that the button width resets to the minimum size and clips the content again, even though the button content itself has not changed.

In what environment did this happen?
  • React Native Navigation version: 8.8.11
  • React Native version: 0.81.x (or even the lates 0.86.x)
  • Has Fabric (React Native's new rendering system) enabled: yes
  • Node version: v22.19.0
  • Device model: reproduced on iOS 26.1 simulator, also iphone 15 ios 26.5 real device
  • iOS version: 26.1, 26.5
Lenguaje dominante
MDX
Estrellas
13.2k
Forks
2.6k
Merge medio
2 d 10 h
PR fusionados (30 d)
6

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de wix/react-native-navigation

Todos los issues de wix/react-native-navigation

Issues similares

Más issues de Mobile Dev

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.