UITableView Cells not showing properly - ios

I've made a table view, and I have a prototype cell that has a height of 100, which I set in the IB. However the cell displays as the original cell height that the prototype cell is set to by default. It should be noted that the table view is nested in a UIContainerView, not sure if that's important, but thought it could have to do with something.
Storyboard (in Xcode)
Simulator

You need to set height for row
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0;//Choose your custom row height
}

Related

How to use dynamic height of UITableViewCell in auto-layout and move other views to up when bottom view is hidden?

I have a UITableViewCell in xib and its outlets in corresponding UITableViewCell subclass. I am returning height of cell from
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) ->CGFloat {
return 400
}
I need to hide some views based on the data available in each row of the table and bottom view should shifted to top of the cell. When I am hiding view from cell then there is empty space left in place of hidden view & bottom views are not shifting to top part of the cell.
Here is How I am hiding cell view.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
.....
cell.opetion4.isHidden = true
cell.opetion3.isHidden = true
}
This is my cell.
After hide 2 middle labels it is looking as follows.
But I want to remove this empty space and want to shift bottom label to top as follows.
At first, make the height of UITableViewCell to UITableView.automaticDimension
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Embed all of your questionLabels in a UIStackView (vertical) excluding bottomLabel. Set AutoLayoutConstraint between UIStackView and bottomLabel.
Set the numberOfLines property of UILabels to 0(zero).
Set the Distribution of the UIStackView as Fill
Then, in your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell method hide the labels. And it will automatically handle the spaces between UILabels
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
cell.questionLabel1.text = labelOneText[indexPath.row]
cell.questionLabel2.text = labelTwoText[indexPath.row]
cell.questionLabel3.text = labelThreeText[indexPath.row]
if labelOneText[indexPath.row] == "" {
cell.questionLabel1.isHidden = true
}
if labelTwoText[indexPath.row] == "" {
cell.questionLabel2.isHidden = true
}
if labelThreeText[indexPath.row] == "" {
cell.questionLabel3.isHidden = true
}
return cell
}
Final Output:
First I suggest you to set UITableViewCell Height to automatic dimensions . Attach all the children to one another and last child to uiview of xib . Now hiding view does not adjust size of cell so you need to play with height constraint of uiview you are hiding .
Make height constraint as strong in IBOutlet else it will crash since cells are re-using and constraint after setting once will become nil . You need to make sure that height constraint are change according to display cell requirement , thats mean for each cell maintain some datasource that decide to show or hide the view every time when cellforrowatIndexpath method called.
Hope this helps
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) ->CGFloat {
return UITableView.automaticDimension
}
now in cell, put all your views and there siblings which you want to hide/show in UIstackview (horizontal). now if you hide one view, it will be hidden and its apace will be also hidden to no white space will be showing, and no need to handle extra constraints. it will all handled by stackview.

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.

TableView Cell Dynamic Height

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
}

Dynamic tableViewCell height

I have a tableViewCell with a label inside that could be multiple lines tall. I've set the label's Lines property to 0. However, when I make the label's text have multiple lines the text gets cut off. Here's how I've set up my storyboard:
Does anybody know how I made the table's cells just tall enough to contain the labels within?
Setting Dynamic Cell height procedure
Pin the label from top and bottom. Please refer following Screen shot
Set numbers of line to 0 of the label as from property inspector of xcode, it can be done from code too please refer following screen shot
Implement delegates of table view mentioned below
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 50 // also UITableViewAutomaticDimension can be used
}
You are missing the bottom constraint from the label to the table view cell (as far as I can tell). In order to make autolayout know how large the height of the cell has to be, you need to supply those constraints.
In addition do not forget to provide the estimatedRowHeight to the table view. If that value is not given, automatic cell sizing will not work.

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