Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed (iOS) setState is not working properly for text inline image #41236 #41287

Closed
wants to merge 2 commits into from

Conversation

ehsemloh
Copy link
Contributor

@ehsemloh ehsemloh commented Nov 1, 2023

Summary:

Closes #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)

Screen.Recording.2023-11-02.at.11.15.47.mov

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).

<div layout="width: 393; height: 852; top: 0; left: 0;" style="" >
  <div layout="width: 393; height: 852; top: 0; left: 0;" style="flex: 1; " >
    <div layout="width: 393; height: 852; top: 0; left: 0;" style="flex: 1; " >
      <div layout="width: 393; height: 241; top: 0; left: 0;" style="padding-top: 59px; " >
        <div layout="width: 393; height: 50; top: 59; left: 0;" style="width: 100%; height: 50px; " >
          <div layout="width: 393; height: 17.3333; top: 0; left: 0;" style="" has-custom-measure="true"></div>
        </div>
        <div layout="width: 393; height: 50; top: 109; left: 0;" style="width: 100%; height: 50px; " >
          <div layout="width: 393; height: 17.3333; top: 0; left: 0;" style="" has-custom-measure="true"></div>
        </div>
        /* Text node that does not contain inline view that is supposed to be there */
        <div layout="width: 393; height: 74.3333; top: 167; left: 0;" style="margin-top: 8px; " has-custom-measure="true"></div>
      </div>
    </div>
  </div>
</div>

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 */
<div layout="width: 48; height: 48; top: 0; left: 0;" style="overflow: hidden; width: 48px; height: 48px; min-width: 0px; min-height: 0px; " ></div>

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 */
<div layout="width: 48; height: 48; top: 0; left: 0;" style="overflow: hidden; width: 32px; height: 32px; min-width: 48px; min-height: 48px; " ></div>

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

Test Plan:

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 1, 2023
@ehsemloh ehsemloh changed the title fixed (iOS) setState is not working properly for text inline image fixed (iOS) setState is not working properly for text inline image #41236 Nov 1, 2023
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Nov 1, 2023
@analysis-bot
Copy link

analysis-bot commented Nov 1, 2023

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 17,661,590 +4,420
android hermes armeabi-v7a n/a --
android hermes x86 n/a --
android hermes x86_64 n/a --
android jsc arm64-v8a 21,039,173 +4,449
android jsc armeabi-v7a n/a --
android jsc x86 n/a --
android jsc x86_64 n/a --

Base commit: 53a2742
Branch: main

@lunaleaps
Copy link
Contributor

Let me try testing this out as well

@lunaleaps
Copy link
Contributor

@ehsemloh can you also provide more detail on how this fixes the setState issue?

@cipolleschi
Copy link
Contributor

/rebase - this comment will rebase this PR on top of main.

@cipolleschi
Copy link
Contributor

...and it failed to push the rebase. :/

@ehsemloh could you please rebase and push? I'd like to see that the tests on Ruby 3.2.0 are passing.
We had a failure in the infra that I fixed yesterday evening.

@ehsemloh
Copy link
Contributor Author

ehsemloh commented Nov 2, 2023

@cipolleschi Thank you so much help out! Let me do that.

@ehsemloh
Copy link
Contributor Author

ehsemloh commented Nov 2, 2023

@cipolleschi done.

@ehsemloh
Copy link
Contributor Author

ehsemloh commented Nov 3, 2023

Hi @NickGerleman , thanks for being involved! I believe this PR is ready for review.

cc: @lunaleaps @cipolleschi

@NickGerleman
Copy link
Contributor

Thank you for adding the detailed description!

@facebook-github-bot
Copy link
Contributor

@NickGerleman has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link

github-actions bot commented Nov 4, 2023

This pull request was successfully merged by @ehsemloh in 36ef646.

When will my fix make it into a release? | Upcoming Releases

@github-actions github-actions bot added the Merged This PR has been merged. label Nov 4, 2023
@ehsemloh ehsemloh deleted the fix/setstate-inline-view branch November 4, 2023 03:03
Othinn pushed a commit to Othinn/react-native that referenced this pull request Jan 9, 2024
…acebook#41236 (facebook#41287)

Summary:
Closes facebook#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).

```
<div layout="width: 393; height: 852; top: 0; left: 0;" style="" >
  <div layout="width: 393; height: 852; top: 0; left: 0;" style="flex: 1; " >
    <div layout="width: 393; height: 852; top: 0; left: 0;" style="flex: 1; " >
      <div layout="width: 393; height: 241; top: 0; left: 0;" style="padding-top: 59px; " >
        <div layout="width: 393; height: 50; top: 59; left: 0;" style="width: 100%; height: 50px; " >
          <div layout="width: 393; height: 17.3333; top: 0; left: 0;" style="" has-custom-measure="true"></div>
        </div>
        <div layout="width: 393; height: 50; top: 109; left: 0;" style="width: 100%; height: 50px; " >
          <div layout="width: 393; height: 17.3333; top: 0; left: 0;" style="" has-custom-measure="true"></div>
        </div>
        /* Text node that does not contain inline view that is supposed to be there */
        <div layout="width: 393; height: 74.3333; top: 167; left: 0;" style="margin-top: 8px; " has-custom-measure="true"></div>
      </div>
    </div>
  </div>
</div>
```
**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 */
<div layout="width: 48; height: 48; top: 0; left: 0;" style="overflow: hidden; width: 48px; height: 48px; min-width: 0px; min-height: 0px; " ></div>
```
**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 */
<div layout="width: 48; height: 48; top: 0; left: 0;" style="overflow: hidden; width: 32px; height: 32px; min-width: 48px; min-height: 48px; " ></div>
```

**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: facebook#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

setState Does Not Work on Inline Image
6 participants