From 36ef6460f04db323d8bbfc8be5e5dc26691a35ae Mon Sep 17 00:00:00 2001 From: ehsemloh Date: Fri, 3 Nov 2023 17:49:05 -0700 Subject: [PATCH] fixed (iOS) `setState` is not working properly for text inline image #41236 (#41287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Closes https://github.com/facebook/react-native/issues/41236 `setState` is not working properly for text inline image ## Fixed demo (please see the animation as in rendering pass rather than re-mounting pass) https://github.com/facebook/react-native/assets/149237137/d4b894bf-2283-4963-8dc7-b8f5a9f81315 ## How it works **Background** Inline views are not included in the Yoga node tree, rather, they are retained as attachments of `NSAttributedString` and are managed by the respective text fragment (`RCTTextShadowView`) that includes them (Code snippet 1). ```
/* Text node that does not contain inline view that is supposed to be there */
``` **Code snippet 1, output of YGNodePrint() in _normal layout_ flow** The layout of such node is handled ad-hoc (_inline layout_) inside `RCTTextShadowView` (Code snippet 2) ``` /* Inline node is calculated on its own */
``` **Code snippet 2, output of YGNodePrint() in _inline layout_ flow** **Problem description** The issue happens when the sizes given by `setState()` are smaller than those in the last round `setState()`. Since the `min-width` and `min-height` are already populated (Code snippet 3) with greater values, the new layout pass gives rather a `noop`. ``` /* min sizes are greater than them in the new style */
``` **Code snippet 3, output of YGNodePrint() in _inline layout (issue)_ flow** **Fix description** This biased `min-width` and `min-height` are given using the **current frame size** (i.e., sizes set in the last round `setState()`) in the _inline layout_ (in `RCTTextShadowView` § Background), whilst the same parameters are given as ~~CGSizeZero~~ `_minimumSize` in _normal layout_ (§ Background). The change of this PR is to unify this behavior of _normal layout_ by using ~~CGSizeZero~~ `_minimumSize` as the input also for _inline layout_. ## Changelog: [IOS] [FIXED] - `setState` is not working properly for text inline image Pull Request resolved: https://github.com/facebook/react-native/pull/41287 Test Plan: - Using **rn-tester** for basic verification - Complete plan: https://docs.google.com/spreadsheets/d/1QLuqNvqX0dM4K68ygRoHDR3S0wcK5umptmjoR7KtkaY/edit?usp=sharing Reviewed By: cipolleschi Differential Revision: D50967547 Pulled By: NickGerleman fbshipit-source-id: b3b6d6919fd9d3302977dc771a41c22f7b796ba5 --- packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm b/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm index 5afa863ad0600c..363170e617ed5c 100644 --- a/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm +++ b/packages/react-native/Libraries/Text/Text/RCTTextShadowView.mm @@ -301,7 +301,7 @@ - (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext localLayoutContext.absolutePosition.x += frame.origin.x; localLayoutContext.absolutePosition.y += frame.origin.y; - [shadowView layoutWithMinimumSize:frame.size + [shadowView layoutWithMinimumSize:{shadowView.minWidth.value, shadowView.minHeight.value} maximumSize:frame.size layoutDirection:self.layoutMetrics.layoutDirection layoutContext:localLayoutContext];