【问题标题】:Control word/text break on React Native <Text> elementReact Native <Text> 元素上的控制字/文本中断
【发布时间】:2019-08-20 17:11:42
【问题描述】:

有没有办法控制文本组件中文本的断字行为?使用 iOS 上的多行文本组件,它会自动中断有断字的文本(我还没有检查过 android,但我也需要它在那里工作)。我希望改变这种行为以打破每个字符的水平,就像你可以做这个 CSS 规则一样:

word-break: break-all;

【问题讨论】:

    标签: react-native


    【解决方案1】:

    使用 split & map 将 &lt;text&gt;str&lt;/text&gt; 转换为 &lt;View&gt;&lt;text&gt;s&lt;/text&gt;&lt;text&gt;t&lt;/text&gt;&lt;text&gt;r&lt;/text&gt;&lt;/View&gt;

    export default class PageCard extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                tail: false,
                longWord: 'longWord longWord bbbbbbbbbbbbbbbbbbbbb longWord longWord longWord',
                longWordTail: ' longWord longWord longWord bbbbbbbbbbbbbbbbbbbbb longWord longWord longWord',
                longWordTail2: ' longWord longWord bbbbbbbbbbbbbbbbbbbbb longWord longWord longWord',
            };
        }
    
        render() {
            return (
                <ScrollView style={{flex: 1, paddingTop: 60, paddingHorizontal: 10}}>
                    
                    <View style={Styles.breakWordWrap}>
                        <Text numberOfLines={2} ellipsizeMode="tail" style={Styles.breakWord}>
                            {this.state.longWord}
                        </Text>
                    </View>
    
                    <View style={Styles.breakWordWrap}>
                        {
                            this.breakWord(this.state.longWord)
                        }
                    </View>
    
                    <View style={[Styles.breakWordWrap, Styles.breakWordWrapTail]}>
                        {
                            this.breakWord(this.state.longWordTail)
                        }
                    </View>
    
                    <View style={[Styles.breakWordWrap, Styles.breakWordWrapTail]}>
                        {
                            this.breakWord(this.state.longWordTail, true)
                        }
                    </View>
    
                    {/*<View style={[Styles.breakWordWrap, Styles.breakWordWrapTail]}>*/}
                    {/*    {*/}
                    {/*        this.breakWord(this.state.longWordTail2, true)*/}
                    {/*    }*/}
                    {/*</View>*/}
    
                </ScrollView>
            )
        }
    
        breakWord = (str = '', tail = false) => {
            let strArr = (tail ? str + ' ' : str).split('');
            return strArr.map((item, index) => tail && strArr.length === index + 1 ?
                <Text key={item + index} style={[Styles.breakWord, Styles.breakWordTail, !this.state.tail && Styles.breakWordTailHide]}>...</Text> :
                (tail && strArr.length === index + 2 ? <Text key={item + index} style={[Styles.breakWord]} onLayout={this.breakWordLast}>{item}</Text>
                    : <Text key={item + index} style={[Styles.breakWord]}>{item}</Text>)
            );
    
        }
    
        breakWordLast = (e) => {
            console.log(e.nativeEvent.layout)
            if (e.nativeEvent.layout.y > 50) {
                this.setState({
                    tail: true
                })
            }
        }
    
    }
    const Styles = {
        box: {
            marginTop: 10,
        },
        title: {
            fontWeight: 'bold',
            color: '#333',
            textAlign: 'center'
        },
        breakWordWrap: {
            flexWrap: 'wrap',
            flexDirection: 'row',
            // not
            borderWidth: 1,
            marginTop: 30,
        },
        breakWordWrapTail: {
            position: 'relative',
            height: 50,
            overflow: 'hidden'
        },
        breakWord: {
            lineHeight: 25
        },
        breakWordTail: {
            position: 'absolute',
            backgroundColor: '#fff',
            right: 0,
            bottom: 0,
            height: 25
        },
        breakWordTailHide: {
            opacity: 0
        }
    }

    【讨论】:

      【解决方案2】:

      文本组件有一个仅限 Android 的 textbreakstrategy 属性,允许对文本的拆分方式进行一些控制。属性值映射到 Android 的原生 android:breakStrategy 值。

      不过,此属性似乎无法转换为 iOS。

      否则,如果您预先了解 Text 值,则可以使用 Soft Hyphen 指示文本拆分

      <Text>aaaaaaaaaaaaaaaaaa bbbbbbbbbbb&shy;CCCCC.</Text>
      

      这将呈现为:

      aaaaaaaaaaaaaaaaaa bbbbbbbbbbb-
      CCCCC.
      

      如果两者都不够,我想这超出了 Text 组件的能力,您可能不得不恢复到另一个组件。也许是呈现简单 html 的一种。

      【讨论】:

      • 谢谢@tvanlaehoven!我也有同样的怀疑。
      【解决方案3】:

      尝试在Text组件的样式中添加flexWrap: "wrap"

      例子:

      代码

      <View style={styles.container}>
        <Text style={styles.text}>{text}</Text>
      </View>
      风格

      export default StyleSheet.create({
        container: {
            flexDirection: 'row',
            alignItems: 'center',
        },
        text: {
          width: 0,
          flexGrow: 1,
          flex: 1,
        }
      });

      【讨论】:

      • 谢谢!但这仍然会在词尾中断,而不是在特定字符处。
      • 我只是更新了上面的帖子。也许它对你有帮助。别忘了给我投票^.^
      • 抱歉,我可能不太清楚。我需要它打破特定的字符,而不是单词。例如如果文本是“aaaaaaaaaaaaaaaaa bbbbbbbbbbCCCCC”并且屏幕上的可用宽度可以适合 a 和 b,但不能适合 C,它会破坏 C 开头的第二个单词。您更新的代码不会这样做。
      猜你喜欢
      • 2016-05-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-30
      • 2021-04-30
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      相关资源
      最近更新 更多