Repository navigation
Conversation
hsource
force-pushed
the
fix/ios-input-line-height-measurement
branch
from
September 23, 2026 21:09
f3007f6 to
5c9ce1d
Compare
The input ignored style.lineHeight: it reached native props but nothing applied it. Store it as baseLineHeight on ENRMInputFormatterStyle and apply it as a paragraph min/max line height (with a baseline offset) to every non-heading paragraph, list items included, and to the typing attributes. Headings use their font size plus the body's extra leading. Measure the input with the same TextKit path as the read-only view and turn off usesFontLeading on the input's layout manager, like React Native's RCTTextLayoutManager. Measurement and drawing now agree, and fonts with built-in leading no longer add extra space. The trailing newline's extra line fragment is kept so a blank last line still counts. A style change now reformats existing plain text too, not only text with inline formatting, so changing lineHeight at runtime applies immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
The playground toggle switches the input between the default line height and 36, to check rendering and auto-grow with headings and lists. Co-authored-by: Cursor <cursoragent@cursor.com>
hsource
force-pushed
the
fix/ios-input-line-height-measurement
branch
from
September 23, 2026 21:13
5c9ce1d to
be3555f
Compare
Author
|
Moved upstream: software-mansion#886 |
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.
Note: this PR has been manually reviewed and is a version of code that's been part of the Wanderlog (wanderlog.com) mobile apps for the past 3 weeks
What/Why?
Fixes software-mansion#615 on iOS. This is the iOS counterpart of the Android fix in #11.
lineHeight was ignored.
style.lineHeightreached the native props, but nothing in the editor applied it.baseLineHeightonENRMInputFormatterStyle, read inapplyInputStyleProps.minimumLineHeight/maximumLineHeight, with a baseline offset so glyphs sit centred in the line like React NativeText.resetBaseTypingAttributesand the per-block typing attributes), so new text picks it up right away.lineHeight - fontSize), the same rule as the Android PR. A large heading doesn't get clipped to the body line height.Measurement and drawing now agree, and match RN.
NSLayoutManagerhadusesFontLeadingat its default ofYES, so each font's built-in leading was added on top of the line height. React Native turns it off, and fix(ios): use same font leading setting for measurement and drawing software-mansion/enriched-markdown#784 did the same for the read-only markdown view. It's now off for the input too. All six layout managers that draw or measure markdown (read-only view, view-free measurement, code blocks, and the input) now read oneENRMLayoutManagerUsesFontLeadingconstant inENRMUIKit.h, which also carries the explanation, so they can't drift apart.measureSize:usedboundingRectWithSizewithNSStringDrawingUsesFontLeading. It now usesENRMMeasureAttributedTextViewFree, the same TextKit path as the read-only view, so the reported height matches what's drawn.ENRMMeasureAttributedTextViewFreegets asubtractExtraLineFragmentflag. The read-only view keeps passingYES. The input passesNO, so a blank last line after a trailing newline still counts toward the height, like RNTextInput. That replaces the old workaround that appended an"I"for trailing newlines.Runtime style changes apply to plain text.
updatePropsused to reformat existing text only when it had inline formatting ranges. ChanginglineHeight,fontSizeorcoloron plain text only affected newly typed text. It now reformats whenever the style changes and the text isn't empty.Compared with software-mansion#664: on iOS that PR adds a similar
baseLineHeight, but headings keep the body line height, and measurement still usesboundingRectWithSizewith font leading on while the view draws with a different layout manager. This PR makes the input follow React NativeText/TextInputlayout for both drawing and measuring.The playground gets the same LH toggle as #11 (the code is identical, so the two PRs merge cleanly in either order), plus an iOS Maestro flow.
Testing
Checks run: clang-format on all changed iOS files,
yarn typecheck, eslint, prettier, and an example app build for the iOS simulator (iPhone 17, iOS 26.4).Test results
line_height_input_ios_test.yamlpasses on the iPhone 17 simulator. Its screenshot step was run in capture mode, because the golden has to come from the CI iOS 26.5 simulator.Left: default line height. Right: after tapping LH 36. The heading, body and list lines are evenly spaced and vertically centred, the heading keeps its larger derived height, and the editor grows to fit the content with no extra space at the bottom.
Manual testing
Setup:
yarn && yarn prepare yarn react-native-example start yarn react-native-example iosIn the example app, open Playground:
fontFamilytoGeeza Pro(or paste Arabic text into the input). Expected: no extra blank space under the last line.EnrichedMarkdownTextscreens (Commonmark, GFM, and a screen withnumberOfLines). Expected: heights are unchanged.Automated flow (screenshot-based; capture the golden first):
PR Checklist