Вложенный текст, вертикальное выравнивание не работает - React Native

Хорошо, давайте сделаем это просто. У меня два Text компоненты, один внутри другого. Первый Text имеет fontSize из 60и вложенный fontSize из 20, Поскольку размер шрифта меняется, вложенный Text сидит основание выровнено. Я хочу вложенный Text вертикально по центру с родительским.

Код

// @flow
import React, { Component } from 'react';
import { Text } from 'react-native';

type PropTypes = {}
export default class SampleVC extends Component<PropTypes> {
    render() {
        return (
            <Text style={{ fontSize: 60 }}>
                Big Text
                <Text style={{ fontSize: 20 }}>Small Text</Text>
            </Text>
        );
    }
}

Текущий выход

Текущий Ouput

Требуемый выход

введите описание изображения здесь

Я знаю, что это простой сценарий, но, поскольку я новичок, чтобы реагировать нативно, я не могу понять это. Я искал по всей сети, но не смог найти ни одного полезного ресурса.

7 ответов

Решение

Невозможно достичь того, что вы пытаетесь, используя только вложенный текст.

Единственный вариант, используйте вид, чтобы обернуть ваши тексты, как,

<View style={{ flexDirection: 'row', alignItems: 'center' }} >
  <Text style={{ fontSize: 60 }}>Big Text</Text>
  <Text style={{ fontSize: 20 }}>Small Text</Text>
</View>

И если вы хотите использовать его часто, создайте свой собственный компонент для вышеуказанного, как,

function CustomNextedText (props) {
  return (
    <View style={{ flexDirection: 'row', alignItems: 'center' }} >
      <Text style={{ fontSize: 60 }}>{props.bigText}</Text>
      <Text style={{ fontSize: 20 }}>{props.smallText}</Text>
    </View>
  );
}

Используйте его где угодно, как и любой другой реактивный компонент,

 <CustomNextedText bigText='Big Text' smallText='Small Text'/>

Надеюсь, поможет.

Вы можете обернуть вложенный текст в представление, но вложенное представление должно иметь ширину и высоту. Если у вас нет проблем с этим ограничением, это хорошее решение.

<Text style={{ fontSize: 60 }}>
      Big Text
      <View style={{ height:40, width:100, justifyContent: 'center', alignItems: 'center' }}>
            <Text style={{ fontSize: 20 }}>Small Text</Text>
      </View>
</Text>

Вы также можете определить smallText lineHeight соответствовать большому тексту:

render() { return ( <Text style={{ fontSize: 60 }}> Big Text <Text style={{ fontSize: 20, lineHeight:60 }}> Small Text </Text> </Text> ); }

Начиная с React-Native v0.63 вы можете рендерить <View/> внутри <Text/>, без предоставления явных размеров для представления. Примечания к выпуску

При принятом ответе, если ваш большой текст достаточно длинный, чтобы занимать несколько строк, маленький текст будет центрирован по вертикали по всему блоку большого текста, а не по конкретной строке.

Итак, вот обновление ответа @Ali S с использованием новой функции. Высота по-прежнему требуется для вертикального центрирования вложенного текста, поэтому для нее установлено значение fontSize большого текста. Ширину можно не указывать, поэтому длина мелкого текста теперь может быть динамической.

function BigSmallText(props) {
    let bigFontSize = 40;
    return (
        <Text
            style={{
                fontSize: bigFontSize,
                lineHeight: bigFontSize,
            }}>
            A very long sentence that spans multiple lines
            <View
                style={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    height: bigFontSize,
                }}>
                <Text
                    style={{
                        fontSize: 14,
                        paddingLeft: 10,
                    }}>
                    SMALL TEXT
                </Text>
                <Text
                    style={{
                        fontSize: 6,
                        paddingLeft: 10,
                    }}>
                    TINY TEXT
                </Text>
            </View>
        </Text>
    );
}

Вы можете добавить оба текста в вид.

<View style={{alignItems: 'center', justifyContent: 'center'}}>
       <Text style={{ fontSize: 60, height:'100%' }}>Big Text</Text>                
       <Text style={{ fontSize: 20, height:'100%' }}>Small Text</Text>
</View>
< View style={{flexDirection:'column'}}>


    <View style={{alignContent:'center'}}>

        <Text style={{fontSize:60}}>{props.bigText}</Text>

    </View>

    <View style={{alignContent:'center'}} >

        <Text style={{fontSize:20}}>{props.smallText}</Text>

     </View>

< /View>

Это кажется странным, но вот что - то , что , кажется, делает работу для меня ( с использованием @Ali SabziNezhad по предложению). Это позволяет делиться текстовыми реквизитами (например, color) и выравнивание ( center в данном конкретном случае)

      function Component() {
    return (
        <CenterText style={{color: 'red'}}>
            Centered <Text style={{fontSize: 50}}>text</Text>
        </CenterText>
    );
}
      export function CenterText({children, ...otherProps}: Text['props']) {
    return (
        <Text {...otherProps}>
            <View 
                style={{flexDirection: 'row', alignItems: 'center'}} 
                children={children} 
            />
        </Text>
    );
}

Мы могли бы иметь более общий текстовый компонент выравнивания:

      export function AlignedText({children, alignItems, ...otherProps}: AlignedTextProps) {
    return (
        <Text {...otherProps}>
            <View 
                style={{flexDirection: 'row', alignItems: alignItems}} 
                children={children} 
            />
        </Text>
    );
}

type Alignment = 'baseline' | 'center' | 'flex-end' | 'flex-start' | 'stretch';
type AlignedTextProps = Text['props'] & {alignItems: Alignment};

Что мы затем можем использовать для определения CenterText:

      export function CenterText(props: TextProps) {
    return <AlignedText alignItems='center' {...props} />;
}

Или прямо как:

      function Component() {
    return (
        <AlignedText style={{color: 'red'}} alignItems='center'>
            Centered <Text style={{fontSize: 50}}>text</Text>
        </AlignedText>
    );
}
Другие вопросы по тегам