Réagissez au texte natif qui sort de mon écran, refusant de s'enrouler. Que faire?


124

Le code suivant peut être trouvé dans cet exemple en direct

J'ai l'élément natif de réaction suivant:

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

var SampleApp = React.createClass({
  render: function() {
    return      (
  <View style={styles.container}>

        <View style={styles.descriptionContainerVer}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >
              Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
            </Text>
          </View>
        </View>

        <View style={styles.descriptionContainerVer2}>
          <View style={styles.descriptionContainerHor}>
            <Text style={styles.descriptionText} numberOfLines={5} >Some other long text which you can still do nothing about.. Off the screen we go then.</Text>
          </View>
        </View>



  </View>);
  }
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);

avec les styles suivants:

var styles = StyleSheet.create({
  container:{
        flex:1,
    flexDirection:'column',
        justifyContent: 'flex-start',
        backgroundColor: 'grey'
    },
    descriptionContainerVer:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'blue',
    // alignSelf: 'center',
  },
  descriptionContainerVer2:{
    flex:0.5, //height (according to its parent)
    flexDirection: 'column', //its children will be in a row
    alignItems: 'center',
    backgroundColor: 'orange',
    // alignSelf: 'center',
  },
  descriptionContainerHor:{
    //width: 200, //I DON\'T want this line here, because I need to support many screen sizes
    flex: 0.3,  //width (according to its parent)
    flexDirection: 'column',    //its children will be in a column
    alignItems: 'center', //align items according to this parent (like setting self align on each item)
    justifyContent: 'center',
    flexWrap: 'wrap'
  },
  descriptionText: {
    backgroundColor: 'green',//Colors.transparentColor,
    fontSize: 16,
    color: 'white',
    textAlign: 'center',
    flexWrap: 'wrap'
  }
});

Cela se traduit par l'écran suivant:

Application de texte hors écran

Comment puis-je empêcher le texte de sortir de l'écran et le garder confiné au milieu de l'écran avec une largeur de soit 80% du parent.

Je ne pense pas que je devrais l'utiliser widthparce que je vais l'exécuter sur BEAUCOUP d'écrans mobiles différents et je veux que ce soit dynamique, donc je pense que je devrais compter totalement sur flexbox.

(C'était la raison initiale pour laquelle j'avais flex: 0.8dans le descriptionContainerHor.

Ce que je veux réaliser est quelque chose comme ceci:

Ce que je veux réaliser

Je vous remercie!

Réponses:


212

J'ai trouvé une solution à partir du lien ci-dessous.

[Texte] Le texte n'habille pas # 1438

<View style={{flexDirection:'row'}}> 
   <Text style={{flex: 1, flexWrap: 'wrap'}}> You miss fdddddd dddddddd 
     You miss fdd
   </Text>
</View>

Production

Vous trouverez ci-dessous le lien utilisateur du profil Github si vous souhaitez le remercier.

Ally Rippley


Edit: mar 09 avril 2019

Comme @sudoPlz l'a mentionné dans les commentaires, cela fonctionne avec la flexShrink: 1mise à jour de cette réponse.

entrez la description de l'image ici


1
Merci, c'est une excellente réponse, mais je l'ai essayé et pour une raison quelconque, cela ne fonctionne pas toujours (je ne sais pas pourquoi: S). flexWrap est un peu floconneux dans React-Native. +1 cependant pour avoir soulevé cela.
SudoPlz

1
^^^ C'est la vraie réponse ici. Acceptez cette opération!
Greg Blass

1
Notez simplement la partie info de cette réponse github.com/facebook/react-native/issues
...

14
J'ai découvert que, dans certains cas, flexShrink: 1appliqué à la vue parent aidera également.
SudoPlz

Cela marche. Merci.
Uddesh_jain

68

C'est un bogue connu . flexWrap: 'wrap'n'a pas fonctionné pour moi mais cette solution semble fonctionner pour la plupart des gens

Code

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

modes

export default StyleSheet.create({
    container: {
        width: 0,
        flexGrow: 1,
        flex: 1,
    }
});

1
m'a juste pris la journée pour trouver votre réponse ... Merci!
Kevin Amiranoff

65

La solution à ce problème est flexShrink: 1.

<View
    style={{ flexDirection: 'row' }}
> 
   <Text style={{ flexShrink: 1 }}>
       Really really long text...
   </Text>
</View>

En fonction de votre configuration, vous devrez peut-être également ajouter flexShrink: 1le <View>parent du parent pour que cela fonctionne, alors jouez avec cela et vous y arriverez.

La solution a été découverte par Adam Pietrasiak dans ce fil.


La vue parentale était aussi la solution pour moi! Si le parent avait flexDirection: 'column', le texte a refusé de s'habiller.
crestinglight le

1
Vous venez de me sauver la vie…
Nikandr Marhal

A parfaitement fonctionné, merci!
fadzb le

31

vous avez juste besoin d'un wrapper pour votre <Text>avec flex comme ci-dessous;

<View style={{ flex: 1 }}>
  <Text>Your Text</Text>
</View>

2
C'est la seule solution appropriée qui fonctionne également
AlwaysConfused

2
En effet, flex: 1c'est tout ce dont vous avez besoin.
instance du

10

Cela fonctionne si vous supprimez flexDirection: rowde descriptionContainerVeret descriptionContainerVer2respectivement.

MISE À JOUR (voir commentaires)

J'ai fait quelques changements pour réaliser ce que je pense que vous recherchez. Tout d'abord, j'ai supprimé le descriptionContainerHorcomposant. Ensuite, j'ai défini les flexDirectionvues verticales sur rowet ajouté alignItems: 'center'et justifyContent: 'center'. Puisque les vues verticales sont maintenant en fait empilées le long de l'axe horizontal, j'ai supprimé la Verpièce du nom.

Vous avez donc maintenant une vue wrapper qui doit aligner verticalement et horizontalement son contenu et l'empiler le long de l'axe x. Je place ensuite simplement deux Viewcomposants invisibles sur le côté gauche et droit du Textcomposant pour faire le rembourrage.

Comme ça:

<View style={styles.descriptionContainer}>
  <View style={styles.padding}/>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Here is a really long text that you can do nothing about, its gonna be long wether you like it or not, so be prepared for it to go off screen. Right? Right..!
    </Text>
  <View style={styles.padding}/>
</View>

Et ça:

descriptionContainer:{
  flex:0.5, //height (according to its parent),
  flexDirection: 'row',
  backgroundColor: 'blue',
  alignItems: 'center',
  justifyContent: 'center',
  // alignSelf: 'center',
},
padding: {
  flex: 0.1
},
descriptionText: {
  backgroundColor: 'green',//Colors.transparentColor,
  fontSize: 16,
  flex: 0.8,
  color: 'white',
  textAlign: 'center',
  flexWrap: 'wrap'
},

Ensuite, vous obtenez ce que je crois que vous recherchiez.

AUTRES AMÉLIORATIONS

Maintenant, si vous souhaitez empiler plusieurs zones de texte dans les vues bleue et orange, vous pouvez faire quelque chose comme ceci:

<View style={styles.descriptionContainer2}>
  <View style={styles.padding}/>
  <View style={styles.textWrap}>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Some other long text which you can still do nothing about.. Off the screen we go then.
    </Text>
    <Text style={styles.descriptionText} numberOfLines={5} >
      Another column of text.
    </Text>
  </View>
  <View style={styles.padding}/>
</View>

textWrapest conçu comme ceci:

textWrap: {
  flexDirection: 'column',
  flex: 0.8
},

J'espère que cela t'aides!


Ok, j'ai changé un peu la question pour refléter ce que je souhaite vraiment réaliser. Maintenant à propos de la réponse: La raison pour laquelle j'ai utilisé flexDirection: rowétait parce que (si j'ai ce droit dans ma tête) flexDirectiondicte la direction dans laquelle les «enfants» de ce parent seront empilés. Maintenant, je voulais que le texte soit l' enfant du milieu chez un parent qui empile les enfants dans une rangée et occupe les 80% de la largeur des parents (quelque chose comme la deuxième photo). Pourriez-vous mettre à jour un peu la réponse pour refléter cela? Je suis prêt à accepter ceci comme réponse.
SudoPlz

Désolé pour la réponse tardive, été occupé. Mais j'ai mis à jour ma réponse, j'espère que c'est ce dont vous aviez besoin.
Eysi

Cette réponse est ABSOLUMENT incroyable .. Exactement ce que je cherchais, merci Elliot !!!!!
SudoPlz

flexDirection: "row"était au cœur de mon problème, j'ai tout essayé sans chance. Changez votre flexDirectionen columnet le texte à l'intérieur sera enveloppé normalement.
quatre

9

Une autre solution que j'ai trouvée à ce problème consiste à envelopper le texte dans une vue. Définissez également le style de la vue sur flex: 1.


2

Je voulais ajouter que j'avais le même problème et flexWrap, flex: 1 (dans les composants de texte), rien de flex ne fonctionnait pour moi.

Finalement, j'ai défini la largeur du wrapper de mes composants de texte sur la largeur de l'appareil et le texte a commencé à s'habiller. const win = Dimensions.get('window');

      <View style={{
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignSelf: 'center',
        width: win.width
      }}>
        <Text style={{ top: 0, alignSelf: 'center' }} >{image.title}</Text>
        <Text style={{ alignSelf: 'center' }}>{image.description}</Text>
      </View>

1
<View style={{flexDirection:'row'}}> 
   <Text style={{ flex: number }}> You miss fdddddd dddddddd 
     You miss fdd
   </Text>
</View>

{flex: aNumber} est tout ce dont vous avez besoin!

Réglez simplement «flex» sur un nombre qui vous convient. Et puis le texte s'enroulera.


Curieusement, c'était en fait la solution qui fonctionnait pour moi.
Dror Bar

1

Dans la version 0.62.2 de React Native, je viens de mettre "flex-shrink: 1" dans Container de mon "Text", mais souviens-toi du flex-direction: row dans View of container. Merci les gars pour l'aide.

Mon code:

export const Product = styled.View`
  background: #fff;
  padding: 15px 10px;
  border-radius: 5px;
  margin: 5px;
  flex-direction: row;
`;

export const ProductTitleContainer = styled.View`
  font-size: 16px;
  margin-left: 5px;
  flex-shrink: 1;
`;

export const ProductTitle = styled.Text`
  font-size: 16px;
  flex-wrap: wrap;
`;
`;

-1

ma solution ci-dessous:

<View style={style.aboutContent}>
     <Text style={[styles.text,{textAlign:'justify'}]}>
        // text here                            
     </Text>
</View>

style:

aboutContent:{
    flex:8,
    width:widthDevice-40,
    alignItems:'center'
},
text:{
    fontSize:widthDevice*0.04,
    color:'#fff',
    fontFamily:'SairaSemiCondensed-Medium'
},

résultat: [d] mon résultat [1]


Vous utilisez donc une largeur statique sur le parent, ce que nous voulions éviter ici.
SudoPlz

-1
<Text style={{width: 200}} numberOfLines={1} ellipsizeMode="tail">Your text here</Text>

Veuillez décrire quelle partie de votre réponse résout les problèmes de PO et pourquoi.
Sebastian B.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.