Родной компонент пользовательского интерфейса динамического размера для React Native

Я хочу построить iOS-ответный родной компонент - аналог Text, где ширина и высота неизвестны, но рассчитаны динамически в зависимости от его содержимого. Как я вижу из отладки, метод RCTText.drawRect вызывается с вычислением rect уже, но мой компонент вызывается с пустым прямоугольником, если я не определял размеры через стили.

Как определить необходимый прямоугольник для пользовательского представления?

Ответ 1

Ответ представлен в концепции "тени". Похоже, что это не документировано, но React Native использует теневые представления для вычисления макета перед фактическим рендерингом. Таким образом, класс RCTShadowText используется для компоновки тега и его функции RCTMeasure:

static css_dim_t RCTMeasure(void *context, float width)
{
  RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
  NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width];
  NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
  NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
  CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;

  css_dim_t result;
  result.dimensions[CSS_WIDTH] = RCTCeilPixelValue(computedSize.width);
  if (shadowText->_effectiveLetterSpacing < 0) {
    result.dimensions[CSS_WIDTH] -= shadowText->_effectiveLetterSpacing;
  }
  result.dimensions[CSS_HEIGHT] = RCTCeilPixelValue(computedSize.height);
  return result;
}

Ответ 2

Вы можете использовать свойство onLayout в текстовом представлении и посмотреть, есть ли у него больше строк, которые вы хотели бы иметь. Таким образом, вы сделали бы следующее:

  • используйте начальную ширину для текстового элемента
  • дождитесь onLayout, чтобы запустить и рассчитать, сколько ширины потребуется для текстового компонента на основе визуализированных измерений.
  • установить расчетную ширину, вызывая перерасчет с расчетной шириной