1

Je ne suis pas sûr si j'approche de cette façon la plus optimale.Un TableView qui "correspond" (ala "sizeToFit") à la taille du contenu de sa cellule dynamique. Puis imbriqué dans un parent UIView qui est également "dimensionné pour s'adapter"

(1) Tout d'abord, je veux un tableauView avec un nombre arbitraire de cellules, dont la hauteur de cellule dynamique varie (basé sur le contenu du serveur web, ne peut pas être calculé à l'avance). Mais je veux que la taille de tableView augmente seulement pour s'adapter à tout le contenu de la cellule (pas plus grand ou plus court). Cette vue de table ne sera PAS scrollable (la vue parente de parent sera).

(2) Ensuite, je veux que la tableView soit imbriquée dans un UIView parent.

J'ai surtout (1) travaillé, même si je ne sais pas si ma méthode est optimale ou hackish. Mais je n'ai certainement pas (2) de travail :(

(Pic ci-dessous) Vue Turqoise est le parent de la vue de la table.Cellules (en rouge) et la taille de la table (en blanc) est correct, mais le parent vue est plus courte que ce qu'elle devrait être.

Screen Shot 2017-07-07 at 9.08.45 PM.png

Après mon changement de code, j'ai le problème inverse. la hauteur mère Grown à environ la bonne hauteur, mais le tableView se est coupée.

Screen Shot 2017-07-07 at 9.10.06 PM.png

C'est le changement de code:

Screen Shot 2017-07-07 at 9.22.31 PM.png

Voir hiérarchie:

Screen Shot 2017-07-07 at 9.11.06 PM.png

Si je ne cherche pas à mettre le tableView dans un UIView parent, la table "taille à des crises" juste à droite:

Screen Shot 2017-07-08 at 10.02.57 AM.png

import UIKit 

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    @IBOutlet var tableView: UITableView! 
    @IBOutlet var tableViewHeightConstraint: NSLayoutConstraint! 

    @IBOutlet var parentView: UIView! 

    @IBOutlet var parentViewHeightConstraint: NSLayoutConstraint! 

    let data = ["this is a short line.", 
       "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Excepteur sint. deserunt mollit anim id est laborum.", 
       "another short line.", 
       "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia." 
       ] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     tableView.delegate = self 
     tableView.dataSource = self 

     tableView.rowHeight = UITableViewAutomaticDimension 
     tableView.estimatedRowHeight = 50 

    } // viewDiDload 
    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 

     // If I add this new frame for the table's parent view, 
     // the table view height gets chopped off. See 3 lines below 
     var newFrameForParent = self.parentView.frame 
     newFrameForParent.size.height = self.tableView.contentSize.height 
     self.parentView.frame = newFrameForParent 
     // But if I comment out the above 3 lines, the table view 
     // height is fine (table height fits actual dynamic content size) 
     // but the table's parent view is shorter than the table view 

     var newFrame = self.tableView.frame 
     newFrame.size.height = self.tableView.contentSize.height 
     self.tableView.frame = newFrame 

     print("viewDidAppear: tableView contentSize w: \(tableView.contentSize.width) h: \(tableView.contentSize.height)") 

    } // viewDidAppear 

    override func viewWillLayoutSubviews() { 
     super.updateViewConstraints() 
     self.tableViewHeightConstraint.constant = self.tableView.contentSize.height 
     //self.parentViewHeightConstraint.constant = self.tableView.contentSize.height + 20 
     print("viewWillLayoutSubviews: tableView contentSize w: \(tableView.contentSize.width) h: \(tableView.contentSize.height)") 
    } // viewWillLayoutSubviews 
    override func viewWillAppear(_ animated: Bool) { 
     //tableView.sizeToFit() 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return data.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath) as! CustomCell 
     cell.cellLabel?.text = data[indexPath.row] 

     print("cell \(indexPath.row) height is: \(cell.frame.height)") 

     return cell 
    } 

} 

La base de code complet est ici: https://github.com/jayliew/UITableViewSizeToFitDynamicHeightCells/tree/master/TableViewFitContent

Je ne sais pas ce que je dois savoir, que je ne sais pas, mais je soupçonne que c'est quelque chose autour de comprendre pleinement comment les vues sont disposées, comment AutoLayout entre en play, avec les cycles de vie viewController comme viewWillAppear, viewWillLayoutSubviews, etc. (comment chaque étape affecte la disposition des vues, avec ou sans AutoLayout). Je ne veux pas seulement résoudre ce problème, mais comprendre l'architecture plus globalement et j'apprécierais que quelqu'un puisse me diriger dans la bonne direction.

Répondre

1

répondre à ma propre question:

La leçon que j'ai appris était de ne pas mélanger avec AutoLayout créer manuellement des cadres et de changer des vues à l'aide de ces cadres. J'ai appris que je devais d'abord définir artificiellement le tableView à une hauteur ginormous, par exemple. 1000, de sorte que les cellules dynamiques seraient "visibles" sur la table. Alors seulement je peux faire une boucle à travers toutes ces cellules, obtenir la hauteur du cadre, les ajouter manuellement, avant de définir la constante de contrainte de hauteur AutoLayout sur tableView pour égaler la somme de toute la hauteur de la cellule.

En outre, ce qui précède devait arriver à l'intérieur de viewDidAppear()

C'était-ce! Exemple de code ici: https://github.com/jayliew/UITableViewSizeToFitDynamicHeightCells

Merci à @ddustin sur Github

Screen Shot 2017-07-13 at 1.45.38 PM.png

Screen Shot 2017-07-13 at 1.45.56 PM.png