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!

SudoPlz
la source

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

Ashok R
la source
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,
    }
});
Dev01
la source
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.

SudoPlz
la source
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>
jsina
la source
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!

Eysi
la source
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.

Joël
la source
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>
mcc
la source
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.

letanthang
la source
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;
`;
`;
Marcelo Tchelão
la source
-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]

Nguyễn Phúc
la source
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>
Saurav
la source
Veuillez décrire quelle partie de votre réponse résout les problèmes de PO et pourquoi.
Sebastian B.