11
votes

Autolayout ignore les détails multi-lignesTextLabel lors du calcul de la hauteur uableviewcell (tous les styles)

Donc, j'essaie d'utiliser les styles UitailViewCell intégrés - spécialement udiableviewCellstylesubtitle - avec une ligne (single) TextLabel mais Multiline DétailTextLabel . Mais la hauteur de cellule calculée (auto) est toujours trop courte et semble ignorer qu'il y a plus d'une ligne de détail.

J'ai essayé d'utiliser NumberOflines = 0, estimérowheighight, UitailViewAutomaticDimension, préférémaxwidthlayout, etc., mais dans toutes les permutations, le comportement - pour tous tous les styles uitables de la cellule uitativeViewCellimension Remplira correctement un multiligne TextLabel (YAY!), mais suppose de manière incorrecte le détaillant TextLabel est à la plupart des lignes simples (Nay!). Par conséquent, les cellules avec un détaillant multiligneTextLabel sont trop courtes et la teneur en cellules se répand sur le haut et le bas de la cellule.

 Entrez la description de l'image ici

J'ai posté une application de test rapide montrant ce comportement sur github ici . L'ajout de lignes de texte supplémentaires est la bonne - tous les styles de cellules augmentent de manière appropriée de la hauteur à accommoder - mais l'ajout de lignes de détail supplémentaires ne change rien de la hauteur de la cellule et provoque rapidement le contenu du contenu; Les détails du texte + sont eux-mêmes aménagés correctement, et ensemble centrés correctement au milieu de la cellule (donc dans ce sens layoutsubviews fonctionne correctement), mais la hauteur globale de la cellule elle-même est inchangée.

Il semble presque comme s'il n'y avait pas de contraintes de haut et de fond réelles entre la Cell.ContentView et les étiquettes, et la hauteur de la cellule est calculée directement à partir de la hauteur du texte (éventuellement multi-lignes) et (seulement un seul Ligne) DétailTextLabel, puis tout est centré sur le milieu de la cellule ... à nouveau, la multiligne textlabel va bien et je ne fais rien de différent entre le texte de la texte et le détailTextLabel, mais seulement l'ancien (correctement) ajuste la hauteur de la cellule.

Donc, ma question est de savoir s'il est possible d'utiliser les styles UitailViewCell intégrés pour afficher de manière fiable multiligne détaillantTextLabels , ou est-ce tout simplement pas possible et vous devez créer une sous-classe personnalisée à la place? [Ou, presque équivalent, sans avoir à remplacer la mise en place dans une sous-classe et rewire toutes les contraintes manuellement].


[4 mai 2016] Conclusion: à partir de l'IOS9 Multi-line détailléTextLabels ne fonctionnent pas comme prévu avec UitablesViewAutomaticDimension; La cellule sera systématiquement trop courte et le texte / détail se déversera sur le dessus et le bas. Soit vous devez calculer manuellement la hauteur de cellule correcte vous-même, soit créer et mettre en page votre propre sous-classe UitailViewCell personnalisée équivalente, ou (voir ma réponse ci-dessous) Sous-classe UitablesViewCell et correction SystemLayoutsizeFitThiority: VerticalFittingPriority: Pour renvoyer le bon Hauteur [recommandé]


0 commentaires

5 Réponses :


1
votes

De mon expérience Les cellules intégrées ne prennent pas en charge la redimensionnement automatique avec des contraintes, je pense que la meilleure solution consiste à créer une cellule personnalisée, il faut vraiment quelques minutes et vous n'avez pas besoin de remplacer la mise en place de layoux, c'est Vraiment simple. Changez simplement le type de la cellule dans l'IB en personnalisage, faites glisser une étiquette, définissez des contraintes (dans l'IB), définissez le nombre de lignes, créez une sous-classe, modifiez la classe de cellules dans l'IB vers votre sous-classe, créez une prise de courant dans la sous-classe. Sous-classe et c'est la plupart des travaux, Je suis sûr qu'il y a beaucoup de tutoriels sur le net que vous pouvez suivre.


3 commentaires

Créer une cellule personnalisée n'est pas un problème, ni un défi. Je souhaite plutôt maximiser la fonctionnalité intégrée de iOS et non inutilement réinventer une roue; Que font-ils extrêmement bien les Uitables existants. Mais l'UitableViewAutomaticDimension semble être cassée pour Multi-Line détailTextLabels . Avant de recourir à la ré-mise en œuvre du style UitailViewCellstylesubtitle, juste pour gérer 2 ou 3 lignes de sous-titre, je souhaite confirmer qu'il n'y a pas d'astuce que j'ai manquée. Ou s'il s'agit d'une fonctionnalité non documentée (c'est-à-dire ne sera jamais corrigé). Ou un bug (c.-à-d. Doit être rapporté et fixé).


Il n'y a pas d'astuce, vous ne pouvez pas modifier la mise en page de contenu prédéfini, comme la valeur par défaut TextLabel DetailtTextLabel et ImageView, si vous définissez l'estimationROWHEight à une hauteur et de la ronde sur utailviewAutomaticDimension et qu'il n'a aucun effet sur les étiquettes par défaut et c'est comme ça qu'ils Travailler depuis des systèmes iOS précédents, ce n'est pas un bug et il n'y a pas d'astuce, peut-être que cela changera à l'avenir et que ce ne sera peut-être pas, mais une solution pratique et rapide consiste à utiliser des cellules personnalisées.


Vous pouvez ajouter ce lien de tutoriel à votre réponse: AppCoda.com/Self-Size-Cells



21
votes

d'autres enquêtes (voir UitailViewCelltest ) Indiquez que lorsque utableViewAutomaticDimension em> est activé Le système appelle -SystemLayoutsizeFittingsize: withhorizontalFittingPriority: VerticalFittingPriority: Code> Pour calculer la hauteur de la cellule et que cela ignore à peu près la hauteur du détailTextLabel dans son calcul (bug!?). En conséquence, pour UitailViewCellstylesubtititle em> la hauteur de la cellule va toujours être trop courte [une seule ligne détailTextLabel strong> peut ne pas se déverser sur la cellule, mais c'est seulement à cause de la Les marges supérieures et inférieures existantes], et pour utailviewcellstylevalue1 em> ou utailviewcellstylevalue2 em> La hauteur sera trop courte chaque fois que le détailTextlabel est plus grand (par exemple plus de lignes) que le texte textlabel strong>. Ceci est tout un point discutable pour utailviewcellstylefault em> qui n'a pas de détaillantTextLabel.

Ma solution consistait à sous-classer et à corriger avec: p> xxx pré>

et dans le Contrôleur d'affichage: P>

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.estimatedRowHeight = 44.0;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}


7 commentaires

J'utilise un certain code basé sur cette réponse pendant un moment et réalisé récemment qu'il ne semblait pas fonctionner correctement lorsqu'il est utilisé dans une vision de table présentée de manière modale. Le problème était que «Drapheight» était renvoyé comme zéro. J'ai constaté que l'ajout de [Self layoutifié] au début de la fonction a résolu le problème.


À votre santé. J'avais également remarqué que parfois la hauteur de la cellule était encore trop courte, le temps premier la cellule a été montré, mais il se fixerait par magiquement peu de temps après (par exemple, faire tourner l'écran). Comme vous le dites, ajoutez [Self layoutifié] fait le tour, merci!


iOS 11 ajoute un double espace ici.


Cette solution a fonctionné pour une vue de table que j'ai appelée à partir d'un contrôleur que j'ai appelé programmatiquement, mais je ne peux pas le faire fonctionner (jusqu'à présent) à l'aide d'un contrôleur mis en place dans le storyboard. Je manque probablement simplement un cadre de scénario quelque part. Aucune suggestion?


Victor - Assurez-vous dans l'interface graphique de Storyboard que vous remplissez votre View avec la Custom UtailviewCell Sous-classe ; Si vous faites glisser-déposer UitablesViewScells dans l'interface graphique, vous le renseignerez avec juste l'UOS Uitables régulier (cassé).


Êtes-vous sûr Ceci est corrigé pour la valeur1 cellules dans iOS 11 ??? Je trouve que cela est très nécessaire même dans iOS 11.2 Malheureusement!


J'ai eu une erreur dans iOS 14.6



4
votes

La réponse de @tiritéa à Swift 3 (merci encore!: D)

// When UITableViewAutomaticDimension is enabled the system calls 
// -systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: to calculate the cell height.
// Unfortunately, it ignores the height of the detailTextLabel in its computation (bug !?). 
// As a result, for UITableViewCellStyleSubtitle the cell height is always going to be too short.
// So we override to include detailTextLabel height.
// Credit: http://stackoverflow.com/a/37016869/467588
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
  self.layoutIfNeeded()
  var size = super.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: horizontalFittingPriority, verticalFittingPriority: verticalFittingPriority)
  if let textLabel = self.textLabel, let detailTextLabel = self.detailTextLabel {
    let detailHeight = detailTextLabel.frame.size.height
    if detailTextLabel.frame.origin.x > textLabel.frame.origin.x { // style = Value1 or Value2
      let textHeight = textLabel.frame.size.height
      if (detailHeight > textHeight) {
        size.height += detailHeight - textHeight
      }
    } else { // style = Subtitle, so always add subtitle height
      size.height += detailHeight
    }
  }
  return size
}


0 commentaires

2
votes

On dirait que Apple a résolu ce bogue dans iOS 11.


3 commentaires

Esperons-le. Je suis surpris quelque chose dans IOS aussi fondamental que UitablementViewCells avec Autolayout peut rester cassé depuis si longtemps ...


Je trouve qu'il est fixé pour les cellules de sous-titres mais pas la valeur1 cellules dans iOS 11.


On dirait que cela a été corrigé dans iOS11.x pour certains styles (sous-titre) mais pas d'autres (valeur1). Geez, Allez Apple, obtenez avec le programme :-(



2
votes

Swift 3 strong>

Après avoir lu diverses réponses, j'ai utilisé la méthode suivante pour obtenir la conduite de textographie de détail étiquette Uitabil validable. Utilisez une cellule de style de base avec une étiquette de titre uniquement et utilisez une chaîne attribuée pour le texte et la vue de texte de détail. N'oubliez pas de modifier le style de cellule de TableView de Sous-titres à la base. P>

    YourTableView.estimatedRowHeight = UITableViewAutomaticDimension
    YourTableView.rowHeight = UITableViewAutomaticDimension
    YourTableView.setNeedsLayout()
    YourTableView.layoutIfNeeded()


1 commentaires

L'utilisation d'une seule chaîne attribuée cassée sur deux lignes et appliquez différents attributs aux deux sous-chaînes pour tenter de reproduire les styles de TextLabel VS DrawTextLabel par défaut de l'IOS, est un KLudge. Il est également utile que d'essayer d'imiter le style de sous-titres; SI N'EST PAS UTILISATION POUR LA FIXATION DU PROBLÈME POUR LES STYLES DE VALEUR1 ou VALEUR2.