web-dev-qa-db-fra.com

Comment dimensionner un UIStackView en fonction de son contenu?

Je voudrais avoir un comportement similaire à celui du <Table> Balise HTML, dans le sens où le cadre est dimensionné en fonction de son contenu.

Dans mon contexte même, j'utilise un UIStackView comme vue de contenu d'un UITableViewCell. Comme les éléments de la cellule sont des informations diverses, la hauteur résultante de la cellule doit être variable.

Ma stratégie consiste à créer par programmation une cellule en tant qu'UIStackView avec un axe .Vertical, comme dans l'extrait de code comme suit:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let sv = UIStackView(frame: tableview.frame)
    sv.axis = .Vertical
    cell.addSubview(sv)
    for i in information {
        let l = UILabel()
        l.text = i
        sv.addSubViewAndArrange(l)
    }

    return cell
}

Malheureusement, la taille de la cellule ne s'adapte pas au contenu, et par conséquent, je dois régler la hauteur de la cellule moi-même, comme suit:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return cellHeight     // a constant
}

Comment pourrais-je résoudre ce problème?

15
Stéphane de Luca

UIStackView est conçu pour augmenter sa taille en fonction du contenu. Pour que cela fonctionne, vous devez configurer les contraintes entre UIStackView et UITableViewCell. Par exemple, voici à quoi ressemblent les contraintes dans le générateur d'interface:

enter image description hereenter image description here

Si vous aimez configurer des contraintes dans le code, cela devrait aussi fonctionner.

Pour démontrer que cela fonctionnera, je l'ai pour la fonction cellForRowAt. Fondamentalement, il place un certain nombre de UILabel à l'intérieur du UIStackView et le nombre d'étiquettes dépend du numéro de ligne.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "TableviewCell", for: indexPath) as! TableviewCell
    for i in 1...indexPath.row + 1 {
        let label = UILabel()
        label.text = "Row \(indexPath.row), Label \(i)"
        cell.stackView.addArrangedSubview(label)
    }
    return cell
}

Voici le résultat final:

https://github.com/yzhong52/AutosizeStackview

6
Yuchen Zhong

J'ai construit cet exemple, j'espère que cela aide, j'ai créé une tableView qui utilise une cellule qui contient une stackView et les vues chargées dans la stackView sont obtenues à partir d'un fichier nib

https://github.com/Joule87/stackView-within-TableViewCell

0
Joule87