ios - Dynamic UITableView row height using UIStackView? -


surprised isn't working out of box, seems important use case stack views. have uitableviewcell subclass adds uistackview contentview. i'm adding labels stack view in tableview(_cellforrowatindexpath:) , tableview set use dynamic row heights, doesn't appear work, @ least in xcode 7.3. under impression hiding arranged subviews in stack view animatable, seems broken well.

any ideas on how working correctly?

broken dynamic row heights

class stackcell : uitableviewcell {     enum visualformat: string {         case horizontalstackviewformat = "h:|[stackview]|"         case verticalstackviewformat = "v:|[stackview(>=44)]|"     }      var hassetupconstraints = false     lazy var stackview : uistackview! = {         let stack = uistackview()         stack.axis = .vertical         stack.distribution = .fillproportionally         stack.alignment = .fill         stack.spacing = 3.0         stack.translatesautoresizingmaskintoconstraints = false         return stack     }()      override init(style: uitableviewcellstyle, reuseidentifier: string?) {         super.init(style: style, reuseidentifier: reuseidentifier)         contentview.addsubview(stackview)     }      required init?(coder adecoder: nscoder) {         fatalerror("init(coder:) has not been implemented")     }      override func updateconstraints() {         if !hassetupconstraints {             hassetupconstraints = true             let viewsdictionary: [string:anyobject] = ["stackview" : stackview]             var newconstraints = [nslayoutconstraint]()             newconstraints += self.newconstraints(visualformat.horizontalstackviewformat.rawvalue, viewsdictionary: viewsdictionary)             newconstraints += self.newconstraints(visualformat.verticalstackviewformat.rawvalue, viewsdictionary: viewsdictionary)             addconstraints(newconstraints)         }         super.updateconstraints()     }      private func newconstraints(visualformat: string, viewsdictionary: [string:anyobject]) -> [nslayoutconstraint] {         return nslayoutconstraint.constraintswithvisualformat(visualformat, options: [], metrics: nil, views: viewsdictionary)     }  class viewcontroller: uitableviewcontroller {      private let reuseidentifier = "stackcell"     private let cellclass = stackcell.self      override func viewdidload() {         super.viewdidload()         configuretableview(self.tableview)     }      private func configuretableview(tableview: uitableview) {         tableview.registerclass(cellclass, forcellreuseidentifier: reuseidentifier)         tableview.separatorstyle = .singleline         tableview.estimatedrowheight = 88         tableview.rowheight = uitableviewautomaticdimension     }      private func newlabel(title: string) -> uilabel {         let label = uilabel()         label.text = title         return label     }      // mark: - uitableview     override func numberofsectionsintableview(tableview: uitableview) -> int {         return 4     }      override func tableview(tableview: uitableview, heightforheaderinsection section: int) -> cgfloat {         return 44.0     }      override func tableview(tableview: uitableview, numberofrowsinsection section: int) -> int {         return 10     }      override func tableview(tableview: uitableview, cellforrowatindexpath indexpath: nsindexpath) -> uitableviewcell {         let cell = tableview.dequeuereusablecellwithidentifier(reuseidentifier, forindexpath: indexpath) as! stackcell         cell.stackview.arrangedsubviews.foreach({$0.removefromsuperview()})         cell.stackview.addarrangedsubview(newlabel("\(indexpath.section)-\(indexpath.row)"))         cell.stackview.addarrangedsubview(newlabel("second label"))         cell.stackview.addarrangedsubview(newlabel("third label"))         cell.stackview.addarrangedsubview(newlabel("fourth label"))         cell.stackview.addarrangedsubview(newlabel("fifth label"))         return cell     }      override func tableview(tableview: uitableview, didselectrowatindexpath indexpath: nsindexpath) {         let cell = tableview.cellforrowatindexpath(indexpath) as! stackcell         (idx, view) in cell.stackview.arrangedsubviews.enumerate() {             if idx == 0 {                 continue             }             view.hidden = !view.hidden         }         uiview.animatewithduration(0.3, animations: {             cell.contentview.layoutifneeded()             tableview.beginupdates()             tableview.endupdates()          })     } } 

it seems work constraints need added in init of uitableviewcell , added contentview instead of cell's view.

enter image description here

the working code looks this:

import uikit class stackcell : uitableviewcell {     enum visualformat: string {         case horizontalstackviewformat = "h:|[stackview]|"         case verticalstackviewformat = "v:|[stackview(>=44)]|"     }      var hassetupconstraints = false     lazy var stackview : uistackview! = {         let stack = uistackview()         stack.axis = uilayoutconstraintaxis.vertical         stack.distribution = .fillproportionally         stack.alignment = .fill         stack.spacing = 3.0         stack.translatesautoresizingmaskintoconstraints = false         stack.setcontentcompressionresistancepriority(uilayoutpriorityrequired, foraxis: .vertical)         return stack     }()      override init(style: uitableviewcellstyle, reuseidentifier: string?) {         super.init(style: style, reuseidentifier: reuseidentifier)         contentview.addsubview(stackview)         addstackconstraints()     }      required init?(coder adecoder: nscoder) {         fatalerror("init(coder:) has not been implemented")     }      private func addstackconstraints() {         let viewsdictionary: [string:anyobject] = ["stackview" : stackview]         var newconstraints = [nslayoutconstraint]()         newconstraints += self.newconstraints(visualformat.horizontalstackviewformat.rawvalue, viewsdictionary: viewsdictionary)         newconstraints += self.newconstraints(visualformat.verticalstackviewformat.rawvalue, viewsdictionary: viewsdictionary)         contentview.addconstraints(newconstraints)         super.updateconstraints()     }      private func newconstraints(visualformat: string, viewsdictionary: [string:anyobject]) -> [nslayoutconstraint] {         return nslayoutconstraint.constraintswithvisualformat(visualformat, options: [], metrics: nil, views: viewsdictionary)     } } 

Comments