I use dynamic height cells for my UITableView with this code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionsCell", for: indexPath) as! QuestionsCell
cell.label1.text = ""
cell.label2.text = ""
cell.label1.text = some text from array
cell.label2.text = some text from array
cell.label1.lineBreakMode = .byWordWrapping
cell.label1.numberOfLines = 0
cell.label1.sizeToFit()
return cell
}
Then I've pinned all constraints in Storyboard for each element (top, bottom, leading and trailing). On iPhone everything works fine, but on iPad when I scroll the UITableView this is happening (dynamic label height):
sizeToFit() only makes cell1 as big as it needs to be for the text.
You also need to use automatic height sizing for the table view cells.
In viewDidLoad,
self.tableView.rowHeight = UITableViewAutomaticDimension
You will also want to make sure you have a vertical constraint from your bold label to the "12 days ago" label, to ensure there is always vertical space between them, so they don't overlap.
you need to implement this delegate method:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
if this does not work then check if there is vertical spacing constraints between top textView and bottom textView.
Related
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.
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.
I have a UITableView. In my tableview l I want to dynamically add another view into my cell and expand the cell height. I have seen some examples but those are with UILabels. UILabels can changes the height according to the text height. But how can I manually add another view and expand those cells?
Please help me
Thanks
If you use the manually calculate the cell height,its easy,after you add another view,you calculate the height,then call reloadData or reloadRowsAtIndexPaths,and return the height in tableview:heightForRowAtIndexPath function.
If you use the auto calculate the cell height.you should let system know how to calculate,you should set the autolayout clearly and completely.You should add the another view`s left、right、top、bottom constraint and the system will auto canculate the height.So the cells will Be expanded.
You can set cell height by override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
Implement these two UITableViewDelegate methods:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
// return estimatedHeight
}
View in your dynamic cell needs to have top, bottom, trailing, leading and height constraints. Setting view height constraint constant will set cell height according to view height.
You can have view height constraint property in your dynamic cell:
#IBOutlet weak var customViewHeightConstraint: NSLayoutConstraint!
Constraint constant value can be changed in cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellId", for: indexPath) as! Cell
switch indexPath.row {
case 0:
cell.customViewHeightConstraint.constant = 100
case 1:
cell.customViewHeightConstraint.constant = 200
case 2:
cell.customViewHeightConstraint.constant = 300
case 3:
cell.customViewHeightConstraint.constant = 400
default:
cell.customViewHeightConstraint.constant = 100
}
return cell
}
I have a expandable tableView, in which when i expand a section, than there are three cell. On firth Cell there is only name and in second cell. It have a big content. Now I want to auto adjust this label height and width according to content.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tblView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let dataArrayTblView = dataArrayForTableView
let titleName = dataArrayTblView.valueForKey("name")
let dueDate = dataArrayTblView.valueForKey("deadlinedate")
let description = dataArrayTblView.valueForKey("description")
cell.titleLabel.text = titleName[indexPath.row] as AnyObject! as! String!
cell.dueDateLabel.text = dueDate[indexPath.row] as? String
cell.descriptionLabel.text = description[indexPath.row] as? String
cell.descriptionLabel.sizeToFit()
cell.textLabel?.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
return cell
}
But not getting complete content
Try to set this. It will automatically adjust the height of the row for you. If it is not working, then you have something wrong with your constraints inside your storyboard.
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
You should use UITableViewAutomaticDimension as row height something like,
// this should be set in viewDidload
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
for that you must use autolayout and should set proper constraints to your label in cell.
Constraint should be in linear chain, I mean your label's top and bottom both constraint must be set and your label should resize according to content so your cell will resize accordingly!
You can refer Self-sizing Table View Cells by Raywenderlich !
Put below in viewDidLoad and set autolayout as per below screenshots.
tblview.rowHeight = UITableViewAutomaticDimension
tblview.estimatedRowHeight = 44
Screenshot 1
Screenshot 2
Screenshot 3
Screenshot 4
Use heightForRowAtIndexPath method to adjust height of row. Calculate
size of string with boundingRectWithSize this method. example:
Try This:
if let YOUR_STRING:NSString = str as NSString? {
let sizeOfString = ns_str.boundingRectWithSize(
CGSizeMake(self.titleLabel.frame.size.width, CGFloat.infinity),options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: lbl.font], context: nil).size
}
I have a Table View called todoTableView with cells that created by the user.
Each cell has Text View.
I want to change the height of the cell by the content of the Text View.
This is what I tried:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: TableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath:indexPath) as! TableViewCell
cell.bounds.size.height = cell.textView.bounds.size.height
return cell
}
Bound Your textview with cell from all sides using marginal constraints.(Leading, Trailing, Top and Bottom constraints)
Disable textView Scrolling
In viewDidLoad() add the following.
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
This will make your cell size according to your textview content size.
Have a look at result :
You don't need to write heightForRowAtIndexPath.
Irfan's answer didn't work for me.
It works after I go to Size Inspector and check "Automatic" for "Row Height".
You should also implement heightForRowAtIndexPath:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return // Calculate your custom row height here.
}