Home > Software engineering >  How to adjust height of UITableView to be the height of the content size?
How to adjust height of UITableView to be the height of the content size?

Time:12-24

I would like to make the table view height dynamic, I would like to add some other views to above below and above the table view. I'm trying to add a table view in a scroll view to make it scroll.

But, I'm not able to find the correct output.

  • Table view rows may vary
  • There may be views that exists above and below of the table
  • Table view should not scroll
  • Only scroll view should scroll

here is my code:

class ViewController: UIViewController {
    
    var content = [Int]()
    
    var scroll: UIScrollView = {
        let view = UIScrollView()
        return view
    }()

    var table: DynamicSizeTableView = {
        let view = DynamicSizeTableView()
        view.estimatedRowHeight = 64
        view.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        return view
    }()
    
    var image: UIImageView = {
        let img = UIImageView(image: UIImage(systemName: "square.and.arrow.up"))
        img.widthAnchor(equalTo: 64)
        img.heightAnchor(equalTo: 64)
        return img
    }()
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        setupViews()
        
        table.delegate = self
        table.dataSource = self
        
        for i in 0...60 {
            self.content.append(i)
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.view.layoutIfNeeded()
    }
    
    func setupViews() {
        self.view.addSubview(scroll)
        scroll.fill(to: view)
        scroll.addSubview(table)
        scroll.addSubview(image)

        table.topAnchor(equalTo: self.scroll.topAnchor)
        table.leadingAnchor(equalTo: self.scroll.leadingAnchor)
        table.trailingAnchor(equalTo: self.scroll.trailingAnchor)
     
        image.topAnchor(equalTo: self.table.bottomAnchor)
        image.bottomAnchor(equalTo: self.scroll.bottomAnchor)
    }
}


extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return content.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
        cell.backgroundColor = .red
        cell.textLabel?.text = "Row \(content[indexPath.row])"
        return cell
    }
    
}

public class DynamicSizeTableView: UITableView {
    override public func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize {
            invalidateIntrinsicContentSize()
        }
    }

    override public var intrinsicContentSize: CGSize {
        return contentSize
    }
}

CodePudding user response:

You should try the stackview. Constrain the stackview to the scrollview and the stackview will handle the height of the element inside. You can give minimum heights inside if you wish.

  lazy var littleVstack:UIStackView = {
    let view = UIStackView(arrangedSubviews: [table,image])
    view.translatesAutoresizingMaskIntoConstraints = false
    view.axis = .vertical
    view.arrangedSubviews[0].heightAnchor.constraint(equalToConstant: 200).isActive = true
    return view
}()

plus do the tableview nonresponsive.

tableView.isUserInteractionEnabled = false

CodePudding user response:

I would suggest the following:

  1. Add a height constraint to your table view.
  2. Set its constant to any value that makes it reasonably visible on the storyboard.
  3. Connect the height constraint to an outlet.
  4. Every time you reload the data on the table view change the height constant.

You may also want to consider the Inset of the table view by adding it to the content size.

Code Sample:

CGFloat height = myTableView.collectionViewLayout. contentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()
  • Related