Skip to content

iOS 16+: Extra bottom padding in multiline MarkdownTextInput (TextKit 2) #742

@safaiyeh

Description

@safaiyeh

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

  1. Setting padding: 0, margin: 0 - No effect
  2. Using flexShrink: 1, flexGrow: 0 - No effect
  3. Wrapping in View with alignSelf: 'flex-start' - No effect
  4. Using onContentSizeChange to set explicit height - Causes content to collapse
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions