I am populating my UITableView from a web service. Here are all the constraints. Some of the items like Cheese Burgers has 10 lines of text which is not displayed.
And here is the result:
To enable automatic resizing of your UITableViewCell, set the rowHeight and estimatedRowHeight of your UITableView in your controller's viewDidLoad() method, like so:
self.tableView.estimatedRowHeight = 150.0
self.tableView.rowHeight = UITableViewAutomaticDimension
And then if you would like or you need to implement the heightForRow UITableViewDelegate method, don't forget to pass again the UITableViewAutomaticDimension to whatever row or section that needs an auto resizing cell, like so:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let section = indexPath.section
if let itemSection = ItemTableViewSections(rawValue: section) {
switch itemSection {
case .header: return 80.0
case .photos: return 95.0
case .note: return UITableViewAutomaticDimension
case .rejectOptions: return 50.0
}
}
return 0
}
Lastly, don't forget to select an answer if an answer really answers your question just like in your last question :)
EDIT: I made a sample project that uses Storyboard and targeting merely iOS 11. All works fine. Just don't forget to set your label's constraint - top, bottom, leading, and trailing. These constraints will be required for autoresizing cell. Lastly, set the UILabel's number of lines to 0.
increase Vertical Content Hugging Priority by 1 of UILabel
When all else fails, try setting Content Compression Resistance Priority to 1000. That's how I fixed my problem.
Related
I have 3 custom cells in Static TableView. All cells have different heights. But I need to make height of newsDetail label dynamic according to its content size. It was easy to make dynamic for dynamic tableview by setting rowHeight and estimatedRowHeight. But it didn't work out for Static TableView. I searched but couldn't find solution for this, anyone please could help me in swift 3?
If you are using Autolayout you need to use,
In viewDidLoad() provide estimated height
tableView.estimatedRowHeight = 60.0 //you can provide any
tableView.rowHeight = UITableViewAutomaticDimension
Implement Delegate method
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension;
}
Need to provide constraint on your label in UITableViewCell.
Top, Bottom, Trailing, Leading and no need to provide any fix height constraint.
And make numberOfLines to 0 of UILabel
I need to set UITableViewCell dynamic height based on it's content.
Here is my demo image:
In this to label which have dynamic content so based on that label content my cell height should change..
I get the constraint error. In this cell two UILabel is available and both have dynamic content size. (I already make the demo with auto resizing cell with only one label.) But in this cell two label are there. So error is xcode suggest me to give Y POS or Height to label, but I already set top constraints. (4 side constraints with label line set to 0 Zero) But still it's fails.
I also try with this code
self.tableView.estimatedRowHeight = 250.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
Here is my demo code
Look at the screenshot of my output. For both the labels , you should give all the four constrains and you have to change the heights of both the labels priority to 750 & set the hugging and resistance priority to 1000. Then you have to change the number of lines to 0 in storyboard
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 250
}
Add this code into viewDidLoad() method:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44
In Swift 3, Use
func tableView(_ tableView: UITableView,estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return HEIGHT // Maximum cell height
}
In table view cell, Set dynamic height constraint to the text view (Greater than or equal) - Maximum text view height
I found the problem. After setting text to UILabel, it doesn't still set correct height frame to its content. In cellForRowAt, just add this:
//these make height frame both of labels became correct
cell.lbName.sizeToFit()
cell.lbAge.sizeToFit()
// update cell layout
cell.layoutIfNeeded()
Have a look at the UITableViewDelegate function tableView(_:heightForRowAt:). It’ll work in your case if you are able to calculate the height for a given index path.
I'm making a simple texting app for practice and the UITableView has lots of cells containing messages.
It works well with one-line messages but, as you can see on the bottom, with multi-line texts the size of the UITableViewCell starts getting in the way and cutting the message short. Just in case, here's the code for my cellForRowAtIndexPath method:
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if usernames[indexPath.row] == PFUser.currentUser()?.username {
cell = tableView.dequeueReusableCellWithIdentifier("text")!
} else {
cell = tableView.dequeueReusableCellWithIdentifier("reply")!
(cell.viewWithTag(2) as! UILabel).text = usernames[indexPath.row]
}
(cell.viewWithTag(1) as! UILabel).text = messages[indexPath.row]
return cell
}
Basically I just need a solution that will enable this app to support multi-line messages. Thanks in advance for any help!
Two things you need to do:
1) In viewDidLoad, specify these:
tableView.rowHeight = UITableViewAutomaticDimension
# The estimated row height number is not that important, just approximate it
tableView.estimatedRowHeight = 140
2) Define all constraints for your custom cell. Make sure top and bottom constraints specifically are defined.
The second step is particularly important.
1) On Storyboard,
In Attribute Inspector section.
Set Lines = 0
2) In func viewDidLoad(),
tableView.estimatedRowHeight = 50.0
tableView.rowHeight = UITableViewAutomaticDimension
You can use self-sizing table view cells and UITableViewAutomaticDimension. This is quite good article about it.
The trick to getting Auto Layout to work on a UITableViewCell is to ensure you have constraints to pin each subview on all sides — that is, each subview should have leading, top, trailing and bottom constraints. Then, the intrinsic height of the subviews will be used to dictate the height of each cell. You’ll do this now.
Then setup rowHeight to UITableViewAutomaticDimension:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
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 have a tableView with static cells inside. One cell contains a map, UITextView and other controls:
This textview has the following constraints:
So far I set up the heightForRowAtIndexPath to the static value for this cell:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if indexPath.row == 0 {
return 311;
}
}
but then when the text is longer, the textview - instead of growing - contains the text inside and user has to scroll it.
Basically it is always 311 in height. I want to change it, so that the whole cell adjust to the textView content.
I tried changing return 311 to return UITableViewAutomaticDimension, but then, when there's no text, the cell shrinks and the controls on the right are not visible.
So my question is - how can I set dynamic height for the cell based on the text inside, but also keep the minimum height of 311?
If you are simply displaying the text and not editing it in any way. You should try using a UILabel and the UITableViewAutomaticDeminsions will work as expected with that provided the constraints are correctly added.
What you can do is add a height constraint to the textView and then increase its size based on the size of the string you obtain. Of course you will need to call layoutIfNeeded too! UITableViewAutomaticDimensions should take care of the rest.
Add a height constraint to the text view >= the minimum value (what it would be when the cell is 311, then set the cell height to automatic.
I don't fully understand your question, but based on what you said maybe this works:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if UITableViewAutomaticDimension > 311 {
return UITableViewAutomaticDimension
}
else {
return 311
}
}
I just check if the cell should be bigger than the minimum of 311, and then return either the minimum or something bigger