web-dev-qa-db-ja.com

UITableViewを展開して、スタックビューのすべてのセルを表示しますか?

UITableViewをスタックビューにフルハイトで表示するのに問題があります。

私のビューツリーは次のようになります。

- View
  - Scroll View
    - Stack View
      - Table View
      - Image View
      - Map View

テーブルビューには動的にデータが入力されますが、これは正常に機能します。問題は、一度に1つの行しか表示されず、リストをスクロールする必要があることです。私が望んでいるのは、テーブルビューが、すべてのセルを表示するために必要なだけの垂直方向のスペースを取ることです。

私は次のようにテーブルの高さを調整しようとしましたが、それが機能したとしても、もっと動的なものが欲しいのですが、スクロールしなくなったテーブルになってしまいます。

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)        
    self.detailsTableView.frame.size.height = 200
}

おそらく調整が必要なのは「スタックビュー」の側面だと思いますが、現時点ではわかりません。誰かが適切な方法を提案できますか?

10
Andre M

UIStackViewは、可能な限りビューを圧縮して、これに対抗するために、高さアンカーと幅アンカーをUITableViewに設定するか、高さと幅の優先順位を設定します。これは、スタックビュー内のテーブルのディメンションを管理する方法の実際の例です。

UIStackViewをインスタンス化して一元的に配置するための拡張機能

まず、UIStackView拡張機能を作成したので、ViewController内にすべてのコードを含める必要はありません。スタックビューをスクロールビュー内に配置するため、配置と設定は異なりますが、このコードを分離すると、独自の調整を行うことができます。

extension UIStackView {

    convenience init(axis:UILayoutConstraintAxis, spacing:CGFloat) {
        self.init()
        self.axis = axis
        self.spacing = spacing
        self.translatesAutoresizingMaskIntoConstraints = false
    }

    func anchorStackView(toView view:UIView, anchorX:NSLayoutXAxisAnchor, equalAnchorX:NSLayoutXAxisAnchor, anchorY:NSLayoutYAxisAnchor, equalAnchorY:NSLayoutYAxisAnchor) {
        view.addSubview(self)
        anchorX.constraintEqualToAnchor(equalAnchorX).active = true
        anchorY.constraintEqualToAnchor(equalAnchorY).active = true

    }

}

UIStackViewのサイズは位置だけに設定するのではなく、その中に含まれるものがサイズを決定します。 UIStackView拡張機能でtranslatesAutoresizingMaskIntoConstraintsがfalseに設定されていることにも注意してください。 (このプロパティをスタックビューに設定する必要があるだけで、そのサブビューは単に動作を継承します。)

データソースコードを含むUITableViewクラス

次に、デモ用の基本的なテーブルクラスを作成しました。

class MyTable: UITableView, UITableViewDataSource {
    let data = ["January","February","March","April","May","June","July","August","September","October","November","December"]
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("SauceCell", forIndexPath: indexPath)
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
}

ビューコントローラでのスタックビューとテーブルの設定

最後に、重要なもの。テーブルをスタックビューに追加するとすぐに、すべてのフレーム情報が無視されます。したがって、自動レイアウトが理解できるようにテーブルの幅と高さを設定するには、最後の2行のコードが必要です。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let table = MyTable(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        table.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SauceCell")
        table.dataSource = table


        let stack = UIStackView(axis: .Vertical, spacing: 10)
        stack.anchorStackView(toView: view, anchorX: stack.centerXAnchor, equalAnchorX: view.centerXAnchor, anchorY: stack.centerYAnchor, equalAnchorY: view.centerYAnchor)

        stack.addArrangedSubview(table)


        table.widthAnchor.constraintEqualToAnchor(view.widthAnchor, multiplier: 1).active = true
        table.heightAnchor.constraintEqualToAnchor(view.heightAnchor, multiplier: 0.5).active = true

    }


}

スタックビューにビューを追加するときは、addArrangedSubview:notaddSubview:を使用することに注意してください。

(私は IStackViewに関するブログ投稿 および 一般的な自動レイアウト に関する他の記事を書いています。これも役立つかもしれません。)

5
sketchyTech

私は同じ問題に直面していましたが、セルフサイジングテーブルビューが必要であることに気付きました。私はこれに出くわしました answer そして@MuHAOSが提案したようなサブクラスを作成しました。問題は発生しませんでした。

class IntrinsicTableView: UITableView {

    override var contentSize:CGSize {
        didSet {
            self.invalidateIntrinsicContentSize()
        }
    }


    override var intrinsicContentSize: CGSize {
        self.layoutIfNeeded()
        return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
    }

}
39
Maria