0
votes

There is table view in scroll view, for the perfect scrolling need height of table view. But there is dynamic height of cell and in cell multiple content with dynamic data like image(calculating height of image with kingfisher library) and content(with 0 number of lines). So unable to calculate height of each cell. So I am using this for getting height of cell:-

let totalCount = self.itemArray.data1.count + self.itemArray.data2.count
   if totalCount != self.totalHeightOfTable.count {
      //Appending height of cell
       self.tableView.reloadData()
       self.totalHeightOfTable.append(cell.frame.height)
       self.heightOfPost = self.totalHeightOfTable
       if totalCount == self.totalHeightOfTable.count {
          // Call back to get height of tableView
           self.getTotalHeightOfTableView?(self.totalHeightOfTable)
        }
  } 

because the tableView is inside a scrollview , I am not able to calculate the height for each cell of the tableView dynamically or at run time. The height I get at runtime is greater and there is a blank white space at the end of the tableView. So the total height for table view is always greater than the sum of all the cells in the table view.

UI structure attached

3

3 Answers

0
votes

You can use the height of the contentSize by taleView.contentSize.height

0
votes

Welcome to Stackoverflow!

You can definitely get the contentSize, and get the height from that, of your tableView. I've been using this method and works every time.

One way to do it is to add an observer, like so:

tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)

and then override your controller's method, observeValue, like so:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let obj = object as? UITableView {
        if obj == self.tableView && keyPath == "contentSize" {
            if let newSize = change?[NSKeyValueChangeKey.newKey] as? CGSize {
                let height = newSize.height // <----- your height!
            }
        }
    }
}

To add, perhaps it would be best if in your viewWillDisappear or deinit method, remove that observer.

0
votes

I understood your problem that you want to calculate dynamic table height with flexible cells height inside tableview and according to this height you want to update your parent scrollview contentSize height .

I want to tell you that please remove your all your height calculation and just place this below simple function in side your view controller.

IMPORTANT:- Don't give any Height Constraint to your table view if you are using AutoLayout from your storyboard or programatically.

kindly take care of your variable names of tableview and scrollview and replace them respectively .

   //MARK:- viewDidLayoutSubviews will call after dynamic height calculation automatically
override func viewDidLayoutSubviews() {
    
    //isScrollEnabled of table view  should be dissable because our table is inside scrollview.
    tableView.isScrollEnabled = false
    
    
    //if above tableView.contentSize.height   not zero and giving acurate value then proceed further and update our parent scroll view contentsize height for height.
    print(tableView.contentSize.height)
    
    
    
    //place some bottom peeding as you want
    let bottomPedding:CGFloat = 30
    
    
    //Finally update your scrollview content size with newly created table height + bottom pedding.
    scrollview.contentSize = CGSize.init(width: scrollview.contentSize.width, height:tableView.contentSize.height + bottomPedding)
    
    
}

if this will work then fantastic then great , rest you can contact me any time we will figure it out. [email protected]