2016-03-26 5 views
17

これは、スタックビューの重要な使用例であると思われるので、これはボックス外では動作しません。私はコンテンツビューにUIStackViewを追加するUITableViewCellサブクラスを持っています。私はtableView(_cellForRowAtIndexPath:)のスタックビューにラベルを追加していますが、tableviewは動的行の高さを使用するように設定されていますが、少なくともXcode 7.3では動作していません。私は、スタックビュー内に配置されたサブビューを隠すことがアニメーション化できるという印象を受けましたが、それも壊れているようです。UIStackViewを使用する動的なUITableViewの行の高さですか?

これを正しく動作させる方法に関するアイデアはありますか?

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 
     for (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() 

     }) 
    } 
} 

答えて

16

このために制約が動作するようだUITableViewCellのINITに追加され、セルのビューの代わりにcontentViewに追加する必要があります。

enter image description here

作業コードは次のようになります。

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) 
    } 
} 
+3

私はプログラム的UIStackViewsを書いて質問を投稿するたびに、誰もが私に嫌っています。だから私は他の誰かがそれをやっているのを見てうれしいです。また、お返事ありがとう;) – Trip

+1

@Trip +1 for programally – netigger

+0

tableViewで 'estimatedRowHeight'を設定しなければなりませんでした。 – Inti

関連する問題