I managed to get this work in the past but now I cannot remember how I did it. I have a UITableView with a dynamic cell and in it, I have an UIView with a height of 174 as a constraint. However, after running the app, it displays the UIView with less height than I defined and also I am getting this error: Warning once only: Detected a case where constraints ambiguously suggest a height of zero for tableviewcell cell's. We're considering the collapse unintentional and using standard height instead:
Those are the constraints I have in the UIView:
I am not able to find a fix for this.
Use this datasource
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 178
}
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.
I want a self sizing table view cell to work in the following. I have four labels in one cell. All the labels will have long contents.
Right now, the problem is - if the second label has more contents, then all the below labels go invisible.
Refer Screen-1 I'm using ExpandingTableView.framework library (github.com/jozsef-vesza/ExpandableTableView) from Github. I've attached the project below.
Screen 1
Project
Looked into your code and fixed issue. Couple of things missing there are listed out below
In your 'MainViewController' add this below code, we actually don't need this code you can ignore if you want. Issue was totally with constraints.
override func tableView(_ tableView: UITableView, heightForRowAt indexPath:IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}`
In your main.storyboard file couple of constraints were missing.
1) Add bottom constraint for 3rd UILabel in TableViewCell
2) Change Main title label height constraints relation form Equal to Greater than of equal
Will work like a charm :)
Senario A:
If I set the label content in cellForRowAtIndexPath, the cell correctly get resized.
Senario B:
If I change the text content in custom action in cell, the cell sized does not get changed.(I do call setNeedsLayout + layoutIfNeeded)
How to fix this?
EDIT:
1) I have set,
myTableView.estimatedRowHeight = 71.0
myTableView.rowHeight = UITableViewAutomaticDimension
2) I have correctly added auto layout constraints.
I was running into this issue, and my problem was that I was constraining the content to self (the UITableViewCell) and not to self.contentView (the contentView OF the cell). Hope this helps someone else who has built their cells all in code!
In my case, the cell's custom size was enabled:
After you change the text of the cell, just reload that particular cell or simply call mainTableView.reloadData().
To reload that cell-
//indexPath is indexPath of cell you just changed label of
mainTableView.reloadRows(at: indexPath, with: .automatic)
In my case, in the same cell I had an imageView in the top left corner with a "center vertically in container" constraint, and a "top space container" constraint.
Obviously to satisfy this two constraint the cell must have an height equal to:
(height of the imageView / 2) + (length of the top space container constraint).
This height is not enough to fit the label text, so my label had only 1 line visible.
After I have deleted the imageView top constraint all went to the right place, in my case i wanted the image to be centered, if the image had to stay in the top left corner I had to take off the "center vertically in container" constraint.
I hope this can help someone.
First of all, I don't specifically know what was your action on UITableViewCell. So, I assume I do that in UITableViewCell selection.
The below answer only work on iOS 9 and above
But, for some reason, it failed to do it in iOS 8 until it scroll. So, I will update the answer for iOS 8.
I have seen you have used UITableView's estimatedRowHeight and rowHeight at your project. So,
Please check the following
Make sure UITableView's estimatedRowHeight and rowHeight include inside viewDidLoad()
Make sure your UILabel lines set to 0
Make sure there is no constraints about height for your UILabel and let the constraints be like that :
If there are other component also included, make sure only bottom and top space constraints included or top space to container margin and bottom space to container margin.
Every time that you want to update the cell, you have to reload tableView no matter what your current situation will be.
So, don't say anything yet before you try this sample project, #Rikh answer still work. May be you are going in wrong direction. Here's the solution. Please do as I said steps by steps and let me know if that didn't work out. You might need to share your sample project which is causing.
Sample Demo - DynamicCellDemo
UPDATE for iOS 8 : update the following code for iOS 8 users
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if #available(iOS 9, *) {
// do nothing
} else {
tblDynamic.reloadData()
}
}
what you can do is set the AutoLayout constraints for the label in present in the cell from all the sides that is from Top, Bottom, Leading and Trailing. Then add the following UITableViewDelegate method to your class.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 500
}
This will do the job. As now content in table view cell automatically adjusts the height of the cell.
Try this if it works:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Add the following in your viewDidLoad()
-(void)viewDidLoad{
[super viewDidLoad];
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
}
I'm trying to call [cell layoutIfNeeded] and [cell.contentView layoutIfNeeded] as I have a number of subviews that have custom constraint logic that I implement in the cell's layoutSubviews method.
However, despite calling both those methods in cellForRowAtIndexPath, when I check the frames of the subviews in the contentView, their frames are still incorrect. I've ensured to call layoutIfNeeded on each subview as well.
Any ideas on why this is happening? The frames are only correct after the cell is displayed, but the height isn't being calculated properly before that.
edit:
I am trying to use the new auto size feature in iOS 8. It's not resizing properly because I have some complicated logic in terms of where my labels go if one is larger than the other. It's not as simple as stacking the labels together - which is why I need the subviews to be laid out correctly before the height is calculated.
I'm not sure what is happening with the code without more information but you should consider using Auto resizing cells. This will resize your cells automatically without having to deal with layout subviews.
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
The layout subviews solution is still used in some edge cases but was mainly used before UITableViewAutomaticDimension came out.