web-dev-qa-db-ja.com

React Native:Textコンポーネントの行数を決定します

タイトルが言うように、私はそれがテキストを与えられた後、テキストコンポーネントの行数を決定する方法を見つけようとしてきました。以下の私の例を見てください。

<Text>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi semper ut ipsum in ultrices. Vivamus fringilla lacinia odio in accumsan. Proin sit amet pellentesque tortor. Nam mollis sit amet ligula id convallis. Etiam in semper diam. Cras id elit consectetur, interdum ante id, tincidunt nisi. Integer non elit placerat, dignissim nibh at, faucibus sem. Curabitur nec posuere turpis. Vivamus rhoncus nulla vitae mi imperdiet, elementum eleifend mi laoreet. Vestibulum molestie turpis non nibh elementum, sed ornare magna tristique. Aliquam erat volutpat. Phasellus volutpat mi vel tempor finibus.
</Text>

実行時に、このTextコンポーネントがレンダリングした行数を確認するにはどうすればよいですか。この数はデバイスによって異なります(たとえば、iPhone 5では画面サイズが小さいため、iPhone 6+よりも多くの行をレンダリングする必要があります)。 Textコンポーネントのソースコードを確認しましたが、探しているものが何もないようです。

私はReact Native 0.24を使用しています。

何か案は?

乾杯。

19
coldbuffet

現代的なソリューションを提供したいと思います。 onTextLayoutイベントがあり、これはlinesの配列を含み、レンダリングされている行数を判別できます。 lines配列には、各行の実際の高さと幅など、テキストが切り捨てられているかどうかを判断するためにさらに使用できるその他の詳細があります。

const NUM_OF_LINES = 5;
const SOME_LONG_TEXT_BLOCK = 'Lorem ipsum ...';

return (
  <Text
    numberOfLines={NUM_OF_LINES}
    onTextLayout={({ nativeEvent: { lines } }) =>
      setState({ showMoreButton: lines.length === NUM_OF_LINES })
    }
  >
    {SOME_LONG_TEXT_BLOCK}
  </Text>
);
10
Arno

Reactのように見えます。ネイティブ0.24はonLayout関数を実装しています
http://facebook.github.io/react-native/docs/text.html#onlayout

onLayout関数
マウントおよびレイアウトの変更時に呼び出されます
{nativeEvent:{レイアウト:{x、y、幅、高さ}}}

したがって、onLayoutコールバック関数を渡し、Textコンポーネントの高さを取得し、行の高さを使用していくつかの計算を行って行数を取得できるように見えます

5

次の式を使用できます。

CPL =幅/(フォントサイズ/フォント定数)

font-constant =各フォントに指定された定数。 CPL = 1行あたりの文字数

ここにいくつかのフォントとその定数があります:

 - Serif Fonts:
 American Typewriter — 2.14
 Baskerville — 2.14
 Georgia — 1.91
 Times New Roman — 2.21

 - Sans-serif Fonts:
 Arial — 1.91
 Calibri — 2.1
 Helvetica Neue — 1.9
 Lucida Grande — 1.91
 Tahoma — 1.91
 Trebuchet MS — 2.11
 Verdana — 1.73

 - Monospace Font:
 Courier New — 1.64

例えば:

function getNumberOfLines(text, fontSize, fontConstant, containerWidth){

    let cpl = Math.floor(containerWidth / (fontSize / fontConstant) );
    const words = text.split(' ');
    const elements = [];
    let line = '';

    while(words.length > 0){
        if(line.length + words[0].length + 1 <= cpl || line.length === 0 && words[0].length + 1 >= cpl){
            let Word = words.splice(0,1);
            if(line.length === 0){
                line = Word;
            }else {
                line = line + " " + Word;
            }
            if(words.length === 0){
                elements.Push(line);
            }
        }
        else {
            elements.Push(line);
            line = "";
        }
    }
    return elements.length;
}
2
0xori

Garrett McCulloughが提供したソリューションは私にとってはうまくいっているようで、コード例を追加したいだけです。

import React from 'react';
import { StyleSheet, Text, View, TouchableHighlight } from 'react-native';

const styles = StyleSheet.create({
    text: {
      fontSize: 24,
      lineHeight: 30,
    }
});

export default class App extends React.Component {

    onLayout = e => {
        const { height } = e.nativeEvent.layout;
        this.count = Math.floor(height / styles.text.lineHeight)
    }

    render() {
        return (
            <View style={styles.page}>
              <Text onLayout={this.onLayout} style={styles.text}>
                Random text. Random text. Random text. Random text. Random text. Random text. Random text.
                Random text. Random text. Random text. Random text. Random text. Random text. Random text.
                Random text. Random text. Random text. Random text. Random text. Random text. Random text.
                Random text. Random text. Random text. Random text. Random text. Random text.
              </Text>

              <TouchableHighlight onPress={() => alert(`text lines count is ${this.count}`)}>
                <Text style={{ fontSize: 50 }}>touch me!</Text>
              </TouchableHighlight>
            </View>
        );
    }
}

https://snack.expo.io/@devastr1/text-lines-count-example

1
Andrew