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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions