Je rencontre un problème avec les vues d'en-tête de section UITableView automatiques/dynamiques qui contiennent un UILabel qui enveloppe (numberOfLines = 0). La hauteur n'est pas calculée correctement, en particulier lorsque vous faites défiler le tableau et que les vues sont réutilisées. Parfois, UILabel est renvoyé à la ligne, parfois tronqué, parfois une ou plusieurs étiquettes ne sont pas visibles, et parfois un espacement supplémentaire existe entre les étiquettes. La vue personnalisée contient une UIStackView verticale avec trois UILabels, dont une enveloppe.
Vous trouverez un exemple complet d'application démontrant le problème à l'adresse https://github.com/outerstorm/tableviewHeaderTest .
Les hauteurs d'en-tête de section sont définies sur automatique dans viewDidLoad avec les éléments suivants:
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 30.0
et ont également implémenté le heightForHeaderInSection suivant juste pour essayer de le faire fonctionner:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
J'ai également essayé d'appeler setNeedsLayout () et layoutIfNeeded () à plusieurs reprises sans succès. Toutes les suggestions seraient grandement appréciées.
Vous trouverez ci-dessous une capture d'écran du comportement observé dans l'application. La première section est coupée et la deuxième section est trop grande:
Ajoutez simplement la fonction estimatedHeightForHeaderInSection
et renvoyez votre hauteur estimée. Cela résoudra votre problème. Téléchargez votre projet modifié de ici
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
{
return 30;
}
J'ai fait face à ce genre de problème récemment.
Je l'ai résolu en définissant preferredMaxLayoutWidth
d'étiquettes multilignes, c'est-à-dire.
Avant de définir la valeur dans les étiquettes, définissez leur preferredMaxLayoutWidth
comme suit:
self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width
self.label2.preferredMaxLayoutWidth = self.label2.frame.size.width
self.label3.preferredMaxLayoutWidth = self.label3.frame.size.width
Une solution de contournement peut être de conserver les vues d'en-tête dans un tableau, puis de renvoyer la hauteur de vue à partir de la méthode de hauteur estimée
for _ in 0 ..< data.count {
let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomHeaderView") as! CustomHeaderView
view.setup()
headerViews.append(view)
}
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat
{
let view = headerViews[section] as? UIView
return (view?.frame.size.height)!
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return headerViews[section] as? UIView
}
En général
heightForHeaderInSection
toujours appelé avant
viewForHeaderInSection
lors de l'utilisation de UITableViewAutomaticDimension, la hauteur de l'en-tête de section ne sera calculée qu'une fois, à moins d'être appelée manuellement tableview.reloadData ().
Dans le code, vous modifiez le texte de l'en-tête de section à chaque fois. la hauteur a été calculée à la première fois et ne change pas automatiquement.
vous pouvez modifier la fonction de configuration pour:
func setup(someNum: Int) {
let text = String(repeating: "This is where the really long text goes so that it will wrap lines appropriately", count: someNum)
mainLabel.text = text
}
et passez l'index de section à la fonction
De la documentation du code:
// Returning this value from tableView:heightForHeaderInSection: or tableView:heightForFooterInSection: results in a height that fits the value returned from
// tableView:titleForHeaderInSection: or tableView:titleForFooterInSection: if the title is not nil.
En d'autres termes. UITableViewAutomaticDimension
est uniquement destiné à être utilisé si vous fournissez un titre de section utilisant titleForHeaderInSection
ou titleForFooterInSection
Ajoutez la méthode self.label1.preferredMaxLayoutWidth = self.label1.frame.size.width
self.label1.numberoflines = 0;
self.label1.linebreakmode = NSLineBreakByWordWrapping;
in dans awakeFromNib Ou Veuillez vérifier cette option une fois https://github.com/krishnasolankiD/multiLineLabel