Repository navigation
Fix TextInput placeholder keeping a removed lineHeight on iOS - #59195
Open
jkasprzyk17 wants to merge 1 commit into
Open
jkasprzyk17 wants to merge 1 commit into
jkasprzyk17 wants to merge 1 commit into
Conversation
UITextField's placeholder label keeps the paragraph style of the previous attributedPlaceholder and applies it to a new placeholder that has none. When a single-line TextInput reuses the view of a TextInput with a lineHeight, or a lineHeight is removed from a mounted one, the new text attributes have no paragraph style, so the placeholder is still measured and drawn with the old line height, below the field's vertical centre. Give the placeholder a paragraph style of its own when the text attributes have none, matching the one a fresh placeholder label uses. Fixes react#59132.
jkasprzyk17
marked this pull request as ready for review
October 19, 2026 14:35
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D126309241. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Fixes #59132.
On iOS, a single-line
TextInputwith aplaceholderand nolineHeightcan draw its placeholder below the field's vertical centre. It happens when the field's native view was last used by aTextInputwith alineHeight(Fabric recyclesRCTTextInputComponentViews), and when alineHeightis removed from a mounted single-line field. Typed text is not affected.UITextField's placeholder label keeps the paragraph style of the previous
attributedPlaceholderand applies it to a new placeholder that has none.RCTNSTextAttributesFromTextAttributesonly adds anNSParagraphStylewhen an alignment, writing direction, line break mode or strategy, or line height is set, so once thelineHeightis gone the new placeholder has no paragraph style, and the label keeps measuring and drawing it with the old line height. SettingattributedPlaceholdertonilfirst doesn't reset it.This change gives the placeholder a paragraph style of its own when the text attributes have none: an
NSMutableParagraphStylewithlineBreakMode = NSLineBreakByTruncatingTail, which is what a fresh placeholder label uses. A paragraph style from the text attributes is used as before. In a right-to-left layoutRCTNSTextAttributesFromTextAttributesalways adds a paragraph style, so the new one only applies to left-to-right layouts withouttextAlign. In a plain UIKit test on the simulator, compared with a freshUITextField, the placeholder renders to the same pixels (English and Hebrew text, with and withoutsemanticContentAttributeforced to right-to-left), andsizeWithAttributes:, whichintrinsicContentSizeuses, returns the same size.The multiline
RCTUITextViewis unchanged: its placeholder is a plainUILabel, which doesn't keep the previous paragraph style.Related: #56487 changes
_placeholderTextAttributesfor fields whoselineHeightis larger than the font; this change is about fields without alineHeight. #59184 (fixed in #59190) is another piece of state that outlives the recycling ofRCTTextInputComponentView. #57748 and #58355 fixed other properties lost on the same single-line/multiline view swap.Changelog:
[IOS] [FIXED] - Fix
TextInputplaceholder drawn below centre after its view is reused from aTextInputwithlineHeightTest Plan:
Added
RCTUITextFieldTestswith two cases:React/Testsisn't compiled by any open source target, so I added the file to theRNTesterUnitTeststarget locally (not part of this change) and ran it on an iPhone 17 Pro simulator, iOS 26.5:testPlaceholderDropsLineHeightRemovedFromTextAttributesfails (((paragraphStyle) != nil) failed), the other test passes** TEST SUCCEEDED **, both tests passI tested manually in RNTester (Debug, new architecture, iPhone 17 Pro simulator, iOS 26.5) with this Playground code:
RNTesterPlayground.js
Steps: tap 1, 2 and 3. The single-line field mounted in step 3 reuses the view of the multiline field from step 1. Then tap Remove lineHeight.
Before: the placeholder of the reused field and the placeholder of the field whose
lineHeightwas removed sit below the red centre line. After: both are centred like the reference field. Tapping Add lineHeight again gives the field itslineHeightplaceholder back, the same as without this change.Commands: