2017-06-30 3 views
0

Ich habe eine UITableViewCell, die eine UICollectionView oben und eine UITableView auf der Unterseite enthält. Die Idee ist, dass eine dynamische Menge von Zellen in der inneren UITableView erstellt wird und die übergeordnete UITableViewCell, die die zwei Untersichten umgibt, wird seine Höhe proportional erhöhen.iOS/Swift: Dynamische UITableViewCell Zeilenhöhe mit eingebetteten UITableView funktioniert nicht

Ich versuche, die estimatedRowHeight + UITableViewAutomaticDimention Funktion der UITableViewCell nutzen, die die Zelle Höhe dynamisch erhöhen können. Es funktioniert jedoch nicht. Es entfernt vollständig das eingebettete UITableView aus Sicht.

Comparison of implementations

Ich habe keine Einschränkungen gemacht, die die Höhe der eingeschlossenen UITableView begrenzen, so dass ich bin mir nicht sicher, warum es nicht funktioniert.

Contraints

Hier ist die Implementierung, die eine dynamisch UITableViewCell Größe zu machen versucht:

class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     navigationItem.title = "Enclosed Table View Example" 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 3 
    } 

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

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 325 // Height for inner table view with 1 cell 
    } 

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return UITableViewAutomaticDimension 
    } 

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
     return 45 
    } 

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "appHeaderCell") as! AppHeaderCell 

     return cell 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell 

     return cell 
    } 
} 

ist Meine einzige Vermutung, dass die Einschränkung bottom = Inner Table View.bottom + 7 das Problem verursacht, sondern die gesamte Ansicht fällt auseinander, wenn diese Einschränkung wird entfernt.

Was kann ich tun, um die komplexe äußere UITableViewCell Höhe auf der Grundlage der Anzahl der Zellen in der eingebetteten UITableView dynamisch Höhe anpassen?

Antwort

0

Obwohl es wie eine gute Idee zu sein scheint, ist die Verwendung von UITableViewAutomaticDimension in Verbindung mit estimatedRowHeight nicht gut in Szenarien wie diese zu verwenden, wo wir allgemeinen Inhalt innerhalb Tabellenansicht Zellen haben. Mit der Methode heightForRowAt können Sie die Größe jeder einzelnen Zelle berechnen, bevor sie die Tabelle zentriert.

Sobald wir wissen, wie viele Zellen in der inneren Tabelle sein werden, müssen Sie ein Array erstellen, dessen Elemente der Anzahl der inneren Zellen entsprechen, die letztlich die Höhe der äußeren Zelle bestimmen, da alle anderen Inhalte konstant sind.

let cellListFromData: [CGFloat] = [3, 1, 4] 

Dieses Array wird uns die Anzahl der Abschnitte in unserer äußeren Tabellenansicht:

func numberOfSections(in tableView: UITableView) -> Int { 
    return cellListFromData.count 
} 

Wir werden jedes Element in diesem Array in eine Zellenhöhe in der folgenden Art und Weise konvertieren:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
    let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell 

    let baseHeight = betweenCellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight 
    let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight 

    return baseHeight + (dynamicHeight * cellListFromData[indexPath.section]) 
} 

Das heißt, innerhalb der heightForRowAt-Methode entfernen wir eine Prototypzelle, die in der resultierenden Ansicht nicht verwendet wird (dequeueReusableCell wird nicht alsbezeichnetin diesem Fall). Wir verwenden diese Prototyp-Zelle, um Informationen über die Konstante und was ist dynamische über den Inhalt der Zelle zu extrahieren. Die baseHeight ist die akkumulierte Höhe aller konstanten Elemente der Zelle (plus der Zwischenzellenabstand) und die dynamicHeight ist die Höhe einer inneren UITableViewCell. Die Höhe jeder Zelle wird dann baseHeight + dynamicHeight * cellListFromData[indexPath.section].

Als nächst wir eine numberOfCells Variable in die Klasse für die benutzerdefinierte Zelle hinzufügen und diese in der Haupttabelle Ansicht in den cellForRowAt Verfahren eingestellt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell 

    cell.numberOfCells = Int(cellListFromData[indexPath.section]) 
    cell.innerTableView.reloadData() 

    return cell 
} 

numberOfCells mit den gleichen cellListFromData gesetzt, die wir früher bekommen die Höhe der Zelle. Außerdem ist es wichtig, reloadData() in der inneren Tabellenansicht nach Aufruf der Anzahl der Zellen, so dass wir diese Aktualisierung in der Benutzeroberfläche sehen.

Hier ist der vollständige Code:

class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
    @IBOutlet weak var outerTableView: UITableView! 
    let cellSpacing: CGFloat = 25 
    let data: [CGFloat] = [3, 1, 4] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return data.count 
    } 

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

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell 

     let baseHeight = cellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight 
     let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight 

     return baseHeight + (dynamicHeight * data[indexPath.section]) 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell 

     cell.numberOfCells = Int(data[indexPath.section]) 
     cell.innerTableView.reloadData() 

     return cell 
    } 
} 

class AppCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate { 
    @IBOutlet weak var innerCollectionView: UICollectionView! 
    @IBOutlet weak var innerTableView: UITableView! 
    var numberOfCells: Int = 0 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

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

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "featureHeaderCell") as! BuildHeaderCell 

     return cell 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "innerCell", for: indexPath) as! InnerCell 

     return cell 
    } 
} 

Methoden zum bezüglich der innere Sammlung Ansicht der Konfiguration hier nicht enthalten, da es nicht mit dem Problem in Zusammenhang steht.

Verwandte Themen