时间:2017-01-18 02:18:01

标签: ios swift uitableview uiview uiscrollview

我正在创建一个可滚动的视图,它是购物车的结帐部分。

这是视图布局

enter image description here

它是一个内置UIView的可滚动视图,其内容大小应根据每个表视图的大小进行调整,UIView内的每个表视图都应该调整它的高度&#39 ; s的内容大小取决于篮子和产品的数量。 (请注意,我想要的是调整整个tableView的大小而不仅仅是其中一个单元格。)

我检查了这个答案Change UITableViewHeight Dynamically,它提供了一些关于如何使我的UITableViews自动调整大小的建议,但我需要UIView和里面的TableViews都是动态大小的。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我不明白为什么你不想把它们合并到一张桌子里。

无论如何.. UIScrollView不适用于自动布局。您必须添加一个与scrollView的父OR具有相同尺寸的contentView,其大小固定。

现在已经不在了,你将tableViews约束到scrollView的contentView,然后覆盖控制器的viewDidLayoutSubviews。在该函数中,您需要获取每个tableView的contentSize并将每个tableView的高度限制为其内容大小。这将使表格全尺寸而不可滚动。

由于scrollView根据其内容自动调整大小,因此您无需执行任何其他操作。

或者,如果您不想使用AutoLayoutScrollView,则可以将UIScrollView contentSize设置为控制器viewDidLayoutSubviews中3个表的contentSize的总和

注意:我没有tableViews的任何示例动态内容,但是如果您希望它们使用动态行大小,则需要执行以下操作:

table.estimatedRowHeight = 300  //Estimation of the average size of the rows.

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

现在对于具有硬编码行高的实际代码(因为我没有动态测试数据):

//
//  ViewController.swift
//  SO
//
//  Created by Brandon T on 2017-01-17.
//  Copyright © 2017 XIO. All rights reserved.
//

import UIKit


class AutoLayoutScrollView : UIScrollView {
    private(set) weak var contentView: UIView!
    private var hConstraint: NSLayoutConstraint!
    private var vConstraint: NSLayoutConstraint!

    init() {
        super.init(frame: .zero)
        self.layout()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.layout()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.layout()
    }

    private func layout() {
        let view = UIView()
        self.contentView = view
        self.addSubview(self.contentView)

        self.contentView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        self.contentView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        self.contentView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        self.contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        self.contentView.translatesAutoresizingMaskIntoConstraints = false
    }

    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        if let parent = self.superview {
            self.leftAnchor.constraint(equalTo: parent.leftAnchor).isActive = true
            self.rightAnchor.constraint(equalTo: parent.rightAnchor).isActive = true
            self.topAnchor.constraint(equalTo: parent.topAnchor).isActive = true
            self.bottomAnchor.constraint(equalTo: parent.bottomAnchor).isActive = true
            self.translatesAutoresizingMaskIntoConstraints = false

            self.hConstraint = self.contentView.widthAnchor.constraint(equalTo: parent.widthAnchor)
            self.vConstraint = self.contentView.heightAnchor.constraint(equalTo: parent.heightAnchor)
            self.hConstraint.isActive = true
            self.vConstraint.isActive = true
        }
    }

    func setHorizontalScrollEnabled(enabled: Bool) {
        self.hConstraint.isActive = !enabled
    }

    func setVerticalScrollEnabled(enabled: Bool) {
        self.vConstraint.isActive = !enabled
    }
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private var scrollView: AutoLayoutScrollView!
    private var topTableView: UITableView!
    private var middleTableView: UITableView!
    private var bottomTableView: UITableView!

    private var topTableHeight: NSLayoutConstraint!
    private var middleTableHeight: NSLayoutConstraint!
    private var bottomTableHeight: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.layout()
    }

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

    func layout() {
        //Init Views
        self.scrollView = AutoLayoutScrollView()
        self.topTableView = UITableView(frame: .zero, style: .plain)
        self.middleTableView = UITableView(frame: .zero, style: .plain)
        self.bottomTableView = UITableView(frame: .zero, style: .plain)

        self.registerClasses()

        //Add Views
        self.view.addSubview(self.scrollView)
        self.scrollView.contentView.addSubview(self.topTableView)
        self.scrollView.contentView.addSubview(self.middleTableView)
        self.scrollView.contentView.addSubview(self.bottomTableView)

        //Layout Views
        self.topTableView.leftAnchor.constraint(equalTo: self.scrollView.contentView.leftAnchor).isActive = true
        self.topTableView.rightAnchor.constraint(equalTo: self.scrollView.contentView.rightAnchor).isActive = true
        self.topTableView.topAnchor.constraint(equalTo: self.scrollView.contentView.topAnchor).isActive = true
        self.topTableView.translatesAutoresizingMaskIntoConstraints = false

        self.middleTableView.leftAnchor.constraint(equalTo: self.scrollView.contentView.leftAnchor).isActive = true
        self.middleTableView.rightAnchor.constraint(equalTo: self.scrollView.contentView.rightAnchor).isActive = true
        self.middleTableView.topAnchor.constraint(equalTo: self.topTableView.bottomAnchor).isActive = true
        self.middleTableView.translatesAutoresizingMaskIntoConstraints = false

        self.bottomTableView.leftAnchor.constraint(equalTo: self.scrollView.contentView.leftAnchor).isActive = true
        self.bottomTableView.rightAnchor.constraint(equalTo: self.scrollView.contentView.rightAnchor).isActive = true
        self.bottomTableView.topAnchor.constraint(equalTo: self.middleTableView.bottomAnchor).isActive = true
        self.bottomTableView.bottomAnchor.constraint(equalTo: self.scrollView.contentView.bottomAnchor).isActive = true
        self.bottomTableView.translatesAutoresizingMaskIntoConstraints = false

        self.topTableHeight = self.topTableView.heightAnchor.constraint(equalToConstant: 0)
        self.middleTableHeight = self.middleTableView.heightAnchor.constraint(equalToConstant: 0)
        self.bottomTableHeight = self.bottomTableView.heightAnchor.constraint(equalToConstant: 0)


        //Set Views Properties
        self.scrollView.setVerticalScrollEnabled(enabled: true)

        self.topTableView.delegate = self
        self.topTableView.dataSource = self
        self.middleTableView.delegate = self
        self.middleTableView.dataSource = self
        self.bottomTableView.delegate = self
        self.bottomTableView.dataSource = self


        //Display Views
        self.topTableView.reloadData()
        self.middleTableView.reloadData()
        self.bottomTableView.reloadData()
    }

    func registerClasses() {
        self.topTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
        self.middleTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
        self.bottomTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        //Update tables constraints to full size.
        self.topTableHeight.constant = self.topTableView.contentSize.height
        self.middleTableHeight.constant = self.middleTableView.contentSize.height
        self.bottomTableHeight.constant = self.bottomTableView.contentSize.height

        self.topTableHeight.isActive = true
        self.middleTableHeight.isActive = true
        self.bottomTableHeight.isActive = true
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (tableView == self.topTableView) {
            return 10
        }

        if (tableView == self.middleTableView) {
            return 15
        }

        if (tableView == self.bottomTableView) {
            return 3
        }

        return 0
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if (tableView == self.topTableView) {
            return 100
        }

        if (tableView == self.middleTableView) {
            return 250
        }

        if (tableView == self.bottomTableView) {
            return 500
        }

        return 0.0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath)

        if (tableView == self.topTableView) {
            cell.contentView.backgroundColor = UIColor.red
        }

        if (tableView == self.middleTableView) {
            cell.contentView.backgroundColor = UIColor.green
        }

        if (tableView == self.bottomTableView) {
            cell.contentView.backgroundColor = UIColor.blue
        }

        return cell
    }
}