Description
When using MarkdownTextInput with multiline={true} and editable={false} on iOS 16+, there is extra bottom padding/spacing after the text content. This spacing is inconsistent and varies based on content length.
Environment
- react-native-live-markdown version: latest
- React Native version: 0.76+
- iOS version: 16.0+ (TextKit 2)
- Device: iPhone (Simulator and physical device)
Minimal Reproduction
import { MarkdownTextInput, parseExpensiMark } from '@expensify/react-native-live-markdown';
import { View } from 'react-native';
function App() {
const content = `**Bold text** and regular text.
This is a second paragraph with more content.
**In short:**
Final paragraph here.`;
return (
<View style={{ flex: 1, padding: 16 }}>
<MarkdownTextInput
value={content}
parser={parseExpensiMark}
editable={false}
multiline
scrollEnabled={false}
style={{
fontSize: 17,
lineHeight: 25.5,
padding: 0,
margin: 0,
}}
/>
{/* This View appears with a gap above it */}
<View style={{ height: 40, backgroundColor: 'red' }} />
</View>
);
}
Expected Behavior
The MarkdownTextInput should size to fit its content exactly, with no extra padding at the bottom.
Actual Behavior
There is extra vertical space (~8-20+ points) between the end of the text content and the bottom of the MarkdownTextInput component. This gap is inconsistent and doesn't respond to padding/margin adjustments.
Root Cause Analysis
Looking at the native iOS code in MarkdownTextInputDecoratorComponentView.mm, I noticed there's a content height fix for iOS < 16 (TextKit 1):
if (@available(iOS 16.0, *)) {
// TextKit 2 - NO FIX APPLIED
_textView.textLayoutManager.delegate = _markdownTextLayoutManagerDelegate;
} else {
// TextKit 1 - Content height fix applied
// See https://github.com/Expensify/App/issues/41567
CGSize contentSize = _textView.contentSize;
CGRect textBounds = [layoutManager usedRectForTextContainer:_textView.textContainer];
contentSize.height = textBounds.size.height + _textView.textContainerInset.top + _textView.textContainerInset.bottom;
[_textView setContentSize:contentSize];
}
This fix corrects the content height for TextKit 1 but is not applied for iOS 16+ (TextKit 2). The issue appears to be related to iOS's UITextView default textContainerInset not being accounted for in the layout.
Attempted Workarounds
- Setting
padding: 0, margin: 0 - No effect
- Using
flexShrink: 1, flexGrow: 0 - No effect
- Wrapping in View with
alignSelf: 'flex-start' - No effect
- Using
onContentSizeChange to set explicit height - Causes content to collapse
- Negative
marginBottom - Works but the value needed is inconsistent based on content
Suggested Fix
Apply a similar content height correction for TextKit 2 on iOS 16+, or expose a prop to control/disable the extra padding.
Description
When using
MarkdownTextInputwithmultiline={true}andeditable={false}on iOS 16+, there is extra bottom padding/spacing after the text content. This spacing is inconsistent and varies based on content length.Environment
Minimal Reproduction
Expected Behavior
The MarkdownTextInput should size to fit its content exactly, with no extra padding at the bottom.
Actual Behavior
There is extra vertical space (~8-20+ points) between the end of the text content and the bottom of the MarkdownTextInput component. This gap is inconsistent and doesn't respond to padding/margin adjustments.
Root Cause Analysis
Looking at the native iOS code in
MarkdownTextInputDecoratorComponentView.mm, I noticed there's a content height fix for iOS < 16 (TextKit 1):This fix corrects the content height for TextKit 1 but is not applied for iOS 16+ (TextKit 2). The issue appears to be related to iOS's
UITextViewdefaulttextContainerInsetnot being accounted for in the layout.Attempted Workarounds
padding: 0,margin: 0- No effectflexShrink: 1, flexGrow: 0- No effectalignSelf: 'flex-start'- No effectonContentSizeChangeto set explicit height - Causes content to collapsemarginBottom- Works but the value needed is inconsistent based on contentSuggested Fix
Apply a similar content height correction for TextKit 2 on iOS 16+, or expose a prop to control/disable the extra padding.