TableView Cell Dynamic Height - ios

I have a UITableView(Table 1). Inside UITableView Cell I have an another UITableView(Table 2).
In Table 2 the rows's height is UITableViewAutomaticDimension.
My requirement is - I want that Table 2 should not be scroll and takes its full height as per number of rows inside it.So, As per this Table 2 's height I need to set Table 1's row height.
I am using Table 2 's contentSize.height, but its not working. I searched a lot but found nothing.
Code :
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let cell = tableView_First.dequeueReusableCell(withIdentifier: "SecondTableViewCell") as! SecondTableViewCell
return cell.second_TableView.contentSize.height
}
Update:
I have debugged the code and found Table 2's cell's estimated height effects the height of Table 1's cell.
i.e- If estimated height of Table 2's cell is 100 and these are 5 cells. Then this cell.second_TableView.contentSize.height gives me 500. Which is wrong.Because cell has different height 10, 20, 30, 40, 10.
Any suggestions will be appreciated.
Thanks!

May you are getting the wrong result because of below two reasons
When you are getting cell.second_TableView.contentSize.height that time your cell.second_TableView might not be loaded completely thus you are getting wrong height.
You are dequeuing new cell rather getting existing loaded cell.
Please try below code:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
//Get existing cell rather deque new one
let cell = tableView_First.cellForRowAtIndexPath(indexPath) as! SecondTableViewCell
//This will force table view to load completely
cell.second_TableView.layoutIfNeeded()
return cell.second_TableView.contentSize.height
}
Hope this will solve your problem.

write this two lines in viewDidLoad,
tableView.estimatedRowHeight = 241
tableView.rowHeight = UITableViewAutomaticDimension
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}

Related

UIStackView in UITableView cell causes jerking when scrolled

I have a UITableView cell with a stack view inside. When the cell is tapped the data source changes and the table view is reloaded. The stack view will now have more views inside and the cell is bigger. However sometimes when I scroll the table there is jerky behaviour. It's almost like the cell size was calculated wrong or something (even though it looks fine). Once the tableview has jerked once it is fine and doesn't do it again until I tap the cell and it adds more stack views.
I am using UITableViewAutomaticDimension on the table view. I have tried removing the cell and the table doesn't jerk. It's defiantly the stack view causing issues.
I set my estimated row height to as close as possible to the calculated height tableView.estimatedRowHeight = 270. No affect. I have also tried implementing the delegate and it makes no difference. I have tried many combinations or sizes and the result is the same. Any idea on what I am doing wrong here? Do stack views in cells just suck?
I think you are on the right track about estimatedRowHeight causing trouble. I encounter this jerking problem and in pretty much every tableView with varying element size. What usually does the job is "caching" cell heights and returning them in delegate, something like:
class MyViewController: UIViewController {
fileprivate var cachedCellHeights = [IndexPath: CGFloat]()
//your code here
}
extension MyViewController: UITableViewDelegate {
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cachedCellHeights[indexPath] = cell.frame.height
}
public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = cachedCellHeights[indexPath] {
return height
}
return 270
}
}
It should work as long as you configure your cell (i.e. add new views to stack view) in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath).
The same applies to section headers.

Dynamic row height in UITableView using custom cell from xib

I'm having a lot of issues getting my custom cells to use the dynamic row height.
Here is the xib of my custom cell.
In viewDidLoad for my table view, I set these values:
self.tableView.estimatedRowHeight = 80.0
self.tableView.rowHeight = UITableViewAutomaticDimension
but it doesn't seem to use the dynamic size when it loads the table.
Below is my cellForRowAtIndexPath function.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Configure the cell...
let cell = Bundle.main.loadNibNamed("RedditCell", owner: self, options: nil)?.first as? RedditPostCellTableViewCell
let post = self.model?.getPostAt(index: indexPath.row)
cell?.title.text = post?.title
cell?.author.text = post?.author
cell?.upvotes.text = "\(post?.upvotes ?? -1)"
return cell!
}
I can't figure out why this isn't working. Any help would be appreciated!
Please try to set the height in the heightForRowAt
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
self.tableView.estimatedRowHeight = 80
return UITableViewAutomaticDimension
}
You don't need to pre-calculate the height. The problem is with your constraints in your custom UITableViewCell. Your constraints should be set up the way to force UITableViewCell to expand to show the whole label or any other content. Just setup constraints similar to my short example project: https://www.transfernow.net/216sw6l1bler?lng=en, and cell height will be automatically set, as you expected.
Screenshot:
In addition to setting the constraints so that the height of all of the elements in the cell + padding can be used to calculated the overall cell height, you must set the number of lines of your labels to zeros and set them to word wrap if these must grow based on content as well.

Change row height depending on which type of tableview cell

I have a table view that has two custom cells. Is there any way to make these two cells have different heights?
Of course,
Here is apple doc Working with Self Sizing TableViewCells
First of all, your cell should be set up with constraints properly.
In second, in your View Controller you should write
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 44.0 // non zero value
in viewDidLoad()
Or you can return different heights form delegate method
func tableView(UITableView, heightForRowAt: IndexPath)
You definitely can do this,
Ensure that your both cell have sufficient to be Fit in Automatic dimension.
In your class where you used tableView write this two lines in viewDidLoad.
//as per your table Outlet name, in my case it's tableView
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 36.0
Or, simply you can also defined height in UITableView method.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Your cell Height
}
You have two ways to do this
From UITableView Method
func tableView(_ tableView: UITableView, heightForRowAt indexPath:
IndexPath) -> CGFloat
in this method you can set height with respect to every cell
for
"indexpath.row"
UITableViewAutomaticDimension
In ViewDidLoad or in other initial method write like this
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 44

Dynamic cells size issue

i'm trying to create a table with many dynamic cells prototype
i'm using the 2 lines of codes in the viewDidLoad()
Table.estimatedRowHeight = 171;
Table.rowHeight = UITableViewAutomaticDimension
however, when the cells need to be higher than 171, it stays 171, until i scroll down and up my tableview, then every cell takes it own really height
so what is the really problem ?
The UITableView asks you for the hight:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
The code is correct, the location is not.
You should not be giving it in viewDidLoad but rather heightForRowAtIndexPath
Try that, it should work. Cheers!

UITableView cell size of screen

I have a table view controller with a navigation controller, and when there is no data for the table view, I want to display a single table cell with instructions on how to add new data. I can display the table cell, but I do not understand how I can get the height of the cell to span the visible height (table height - navigation item height). My goal is to have the label inside of my table cell be vertically centered in the device. I've tried using self.tableView.frame.height, but that gives me the scrollable height, which is larger than the visible area.
Edit: I failed to mention I'm doing this from tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat.
I have found a Good Enoughâ„¢ answer to my own question:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
tableView.isScrollEnabled = false
return tableView.frame.height - (self.navigationController?.navigationBar.frame.height)!
}

Resources