UITableViewCell Auto Sizing Issue Swift - ios

This is the custom UITableViewCell I've designed In a xib. The selected element is a UILabel, which is required to be expand with respect to amount of text.
In storyboard cell each element has a constant height with spacing.
Here's the code that I have in a UITableViewController:
class TableViewController: UITableViewController {
private var exampleContent = ["This is a short text.", "This is another text, and it is a little bit longer.", "Wow, this text is really very very long! I hope it can be read completely! Luckily, we are using automatic row height!, Wow, this text is really very very long! I hope it can be read completely! Luckily, we are using automatic row height!"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
tableView.estimatedRowHeight = 224.0
tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("DescriptionOnlyCell", owner: self, options: nil)?.first as! DescriptionOnlyCell
cell.label.numberOfLines = 0
cell.label.text = exampleContent[indexPath.row]
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return exampleContent.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Output of the code is same exactly as the storyboard cell, no dynamic resizing.
I've read a few threads on stackover and most of them explains same like the code posted above. Though I suspect there's some issue with the storyboard constraints. Any hint would be really helpful.

Instead of setting the constant height values for your labels, set the top and the bottom spacing constraints for all elements and remove height constraints or set their priority lower.

Do the following for the selected label :
Set number of lines = 0
Set lineBreak mode = WordWrap
Set height constraint to >= 15
I am relying on the info you shared that vertical spacing for all UI components is set.

I hope this would fix your resizing.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.layoutIfNeeded()
}

Related

Swift UITableViewCell separatorStyle breaking autolayout on iPhone MIni

I have a UITableView which has a UITableViewCell which contains a UIImageView.
The constraints are setup such that the UIImageView has padding 20 points at the top and sides, and a size ratio of 1:1, so the UIImageView will always be square regardless of the device width.
I apply a cornerRadius to the UIImageView so the image is circular.
However.... the autolayout doesn't seem to work on the first load. But after the first load, it works perfectly.
I have tried every known combination of setNeedsLayout or layoutIfNeeded - both inside the UITableViewCell and in the UITableView code. Nothing works the first time it loads.
Please help!
Code looks like this:
class CircularProfileCell: UITableViewCell {
#IBOutlet weak var circularView: UIView!
func setup() {
circularView.layer.cornerRadius = circularView.bounds.height / 2
}
}
class CircularProfileVC: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.separatorStyle = .none
self.tableView.register(UINib(nibName: "CircularProfileCell", bundle: nil), forCellReuseIdentifier: "CircularProfileCell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CircularProfileCell", for: indexPath) as! CircularProfileCell
cell.setup()
return cell
}
}
Setup looks like this:
Because corner radius is a layer property it does not always play well with auto layout. In addition, I guess you set it up with frame properties of the view (i.e imageView.layer.cornerRadius = imageView.bounds.height/2).
Hence you should try and set the corner radius on the layoutSubviews() function of the cell. This will make sure to render the correct size
override func layoutSubviews() {
super.layoutSubviews()
imageView.layer.cornerRadius = imageView.bounds.height/2
...
}
This only happens when the tableView.separatorStyle = .none
So to fix it I simply leave the separator on, but set the separator color to clear
self.tableView.separatorStyle = .singleLine
self.tableView.separatorColor = UIColor.clear
Thanks to #CloudBalacing for the help. More info about this problem here

Two label align vertically in tableView cell auto resizing swift

Try to auto resizing two labels align vertically within a cell, is that possible?
In the storyboard, we have to set autolayout, since I want to auto resizing two labels(one is on top of another).
I can't set each height so that the storyboard doesn't know what is the height of these two labels so it shows an error for autolayout.
if I click "Add Missing Constraints" button it will add a height for "subtitle"
or I can set height for "title" rather than "subtitle",
or make "title" equal to "subtitle" it will still accept.
here is the result:
A workaround will be separate these two to a different cell.
Any better solution? or am I just simply forget to do anything?
P.S. I'm using Xcode 8 with iOS 10.3.
Try setting out Proper constraints for both the labels-:
Storyboard-:
Constraints for first label-:
Constraints for second label-:
Controller class(use Automatic Dimensions for table view)-:
class ViewController1: UIViewController {
var dataForTableView:[ProductImage]?
#IBOutlet weak var secondTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
secondTable.estimatedRowHeight = 96
secondTable.rowHeight = UITableViewAutomaticDimension
// CHECK FOR DATA
//print(dataForTableView?[0].url as Any)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController1 : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! testingCell2
cell.backgroundColor = UIColor.blue;
cell.secondLabel.text = "agfhjsgfhjsgdshgfhjsfjhvhssajs hjfbvhjfbvjhfgafgfhlgkaghkfakfhkflbvhfbvhfvbhfv ah fvfhbvfjhvbfhdavhfvhv"
return cell
}
// Number of sections in table
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}// Default is 1 if not implemented
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return UITableViewAutomaticDimension
}
}
Output-:
I hope that is what you looking for, let me know if any issues.Thanks

Self-Sizing Table View Cell in Xcode 9

I have a UITableViewController where the cell's self sized correctly using Xcode 8 and Swift 3. Now that I'm using Xcode 9 and Swift 4, they aren't expanding and are just using the default height of 44.
(I have about a sentence or two in each UITableViewCell)
I was using this before:
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
... but was able to comment it out because per Updating Your App for iOS 11 said that the default would be self-sizing now:
I've tried playing around with changing the deployment target to iOS 11, playing around in Storyboard (but I'm using a Table View Cell style Basic so there is not much AutoLayout to be done), and I can't figure out what is going on.
I have the UILabel title set to 0 Lines, and have Line Break Word Wrap, but still not getting anywhere close to getting the cell to expand based on the text content inside of it in Xcode 9. Any ideas?
Thanks!
Edit:
Here's the options (that I don't have) for pinning since it is a Basic cell:
I had the same problem and solved it with to lines of code:
class MyTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
}
Maybe it is a bug in Xcode.
Update
New in Xcode 9 beta 3:
Interface Builder now supports setting the estimatedRowHeight of UITableView. This allows self-sizing table cells by setting the estimated height to a value other than zero, and is on by default. (17995201)
I had the same broken table view issue. Fix was just one click.
Go to your xib or storyboard scenes with table views, go to the size inspector, and you'll see the table view heights (even on dynamic table views) as 44, and sections will be 22. Just click "automatic" and boom, it will present as expected.
Note that I also specify the following in viewDidLoad of the UITableViewController subclass (layoutSubviews solves issues with the first load of a tableViewController not positioning correctly in relation to a non-translucent navBar).
self.tableView.estimatedRowHeight = 180;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.tableView layoutSubviews];
In addition to
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
you should set a height constraint for the contentView of the tabeleViewCell.
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let height: CGFloat = 200
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
I got the same issue and I read about it in many documentation, satisfying answer was something like this, You have to check both options in order to get proper height, because estimated height is needed for initial UI setup like scrollview bars and other such stuff.
Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
When you create a self-sizing table view cell, you need to set this property and use constraints to define the cell’s size.
The default value is 0, which means there is no estimate. (Apple Documentation)>
see this image for storyboard
Also note that there is a bug in xCode 9, when you try to apply Lazy loading in automatic height calculation, it will scroll unexpectedly, so I'll recommend you to use programmatic way in this regard.
self.postTableView.estimatedRowHeight = 200;
self.postTableView.rowHeight = UITableViewAutomaticDimension;
something Like this. Thanks!
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tblview: UITableView!
var selectindex = -1
var arrnumber = ["1","2","3","4","5"]
var image = ["index.jpg","rose-blue-flower-rose-blooms-67636.jpeg","index.jpg","rose-blue-flower-rose-blooms-67636.jpeg","index.jpg"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrnumber.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)as! ExpandableTableViewCell
cell.lblnumber.text = arrnumber[indexPath.row]
cell.img.image = UIImage(named: image[indexPath.row] as! String)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if (selectindex == indexPath.row)
{
return 250
}
else{
return 60
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if(selectindex == indexPath.row)
{
selectindex = -1
}else{
selectindex = indexPath.row
}
self.tblview.beginUpdates()
self.tblview.endUpdates()
}
}
For me, Safe Area was checked. Unchecking "Safe Area" did the work for me.

Autosizing UITableView inside custom UIView for section

I have created UIViewController and added UITableView on it (pinned to all four edges with autolayout).
Then I set estimatedRowHeight (44) and rowHeight (UITableViewAutomaticDimension) and returned 5 custom cells. And it worked.
Now, I want to add custom UITableViewHeaderFooterView that would have dynamic height.
I'm doing next:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 88.0
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return R.nib.orderStatusHeaderView.firstView(owner: self)!
}
My OrderStatusHeaderView is a xib view that has UITableView on it pinned to all 4 edges with autolayout.
OrderStatusHeaderView:
final class OrderStatusHeaderView: UITableViewHeaderFooterView {
#IBOutlet weak var tableView: UITableView! {
didSet {
tableView.dataSource = self
tableView.delegate = self
tableView.rowHeight = 44.0
}
}
}
extension OrderStatusHeaderView: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "\(indexPath.row)")
cell.textLabel?.text = "\(indexPath.row)"
cell.backgroundColor = .red
return cell
}
}
This displays like:
And when I tap or scroll, all red cells disappears. What could it be? And how to make UITableView dynamically load content and UITableViewHeaderFooterView will size itself so it fit UITableView.contentSize. Is it possible?
Check out:
tableView(_:estimatedHeightForFooterInSection:)
and
tableView(_:heightForFooterInSection:)
You also have the equilavant for headerInSection.
Since you are asking for a table's header and footer view, you can skip the delegate methods you describe. Those (as the name implies) are for SECTION headers and footers.
When you set a view that is using AutoLayout as the table's header or footer, the its frame still has a zero height (That's why buttons in such view for example won't work as they are not receiving the touches).
To correctly size a table's header or footer views using AutoLayout you have to apply a trick to actually calculate the height yourself, and set the headerView again. It is described in detail in many posts like these:
https://stackoverflow.com/a/28102157/756039
https://gist.github.com/marcoarment/1105553afba6b4900c10
http://collindonnell.com/2015/09/29/dynamically-sized-table-view-header-or-footer-using-auto-layout/
http://roadfiresoftware.com/2015/05/how-to-size-a-table-header-view-using-auto-layout-in-interface-builder/
Hope this helps.

Dynamic Height Issue for UITableView Cells (Swift)

Text data of variable length are being injected into tableview cell labels. In order for each cell height to be properly sized, I have implemented in viewDidLoad():
self.tableView.estimatedRowHeight = 88.0
self.tableView.rowHeight = UITableViewAutomaticDimension
This estimates the height to be 88.0 pixels and should resize the height automatically if larger. It works perfectly for cells that have yet to be scrolled to (as UITableViewAutomaticDimention is called upon scrolling to the cell), but not for the cells that are initially rendered onscreen upon loading the table with data.
I have tried reloading the data (as suggested in many other resources):
self.tableView.reloadData()
in both viewDidAppear() and viewWillAppear() and it did not help. I am lost.. does anyone know how to render the dynamic height for the cells loaded initially on screen?
Try This:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
EDIT
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Swift 4
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Swift 4.2
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Define above Both Methods.
It solves the problem.
PS: Top and bottom constraints is required for this to work.
Here is example
Use this:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300
and don't use: heightForRowAtIndexPath delegate function
Also, in the storyboard don't set the height of the label that contains a large amount of data. Give it top, bottom, leading, trailing constraints.
SWIFT 3
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 160
AND!!!
In storyBoard: You HAVE TO set TOP & BOTTOM constraints for your Label.
Nothing else.
This strange bug was solved through Interface Builder parameters as the other answers did not resolve the issue.
All I did was make the default label size larger than the content potentially could be and have it reflected in the estimatedRowHeight height too. Previously, I set the default row height in Interface Builder to 88px and reflected it like so in my controller viewDidLoad():
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0
But that didn't work. So I realized that content wouldn't ever become larger than maybe 100px, so I set the default cell height to 108px (larger than the potential content) and reflected it like so in the controller viewDidLoad():
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 108.0
This actually allowed the code to shrink down the initial labels to the correct size. In other words, it never expanded out to a larger size, but could always shrink down... Also, no additional self.tableView.reloadData() was needed in viewWillAppear().
I know this does not cover highly variable content sizes, but this worked in my situation where the content had a maximum possible character count.
Not sure if this is a bug in Swift or Interface Builder but it works like a charm. Give it a try!
Set automatic dimension for row height & estimated row height and ensure following steps:
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
For Example: if you have a label in your UITableviewCell then,
Set number of lines = 0 (& line break mode = truncate tail)
Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.
Here is sample label with dynamic height constraints.
For Swift 3 you can use the following:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Dynamic sizing cell of UITableView required 2 things
Setting the the right constraint of your view inside the table view cell (mostly it includes giving your view proper top , bottom and traling constraints)
Calling these properties of TableView in viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
This is a wonderfull tutorial on self-sizing (dynamic table view cells) written in swift 3 .
In my case - In storyboard i had a two labels as in image below,
both labels was having desired width values been set before i made it equal. once you unselect, it will change to automatic, and as usual having below things should work like charm.
1.rowHeight = UITableView.automaticDimension, and
2.estimatedRowHeight = 100(In my case).
3.make sure label number of lines is zero.
In addition to what others have said,
SET YOUR LABEL'S CONSTRAINTS RELATIVE TO THE SUPERVIEW!
So instead of placing your label's constraints relative to other things around it, constrain it to the table view cell's content view.
Then, make sure your label's height is set to more than or equal 0, and the number of lines is set to 0.
Then in ViewDidLoad add:
tableView.estimatedRowHeight = 695
tableView.rowHeight = UITableViewAutomaticDimension
To make autoresizing of UITableViewCell to work make sure you are doing these changes :
In Storyboard your UITableView should only contain Dynamic Prototype Cells (It shouldn't use static
cells) otherwise autoresizing won't work.
In Storyboard your UITableViewCell's
UILabel has configured for all 4 constraints that is top, bottom,
leading and trailing constraints.
In Storyboard your UITableViewCell's
UILabel's number of lines should be 0
In your UIViewController's
viewDidLoad function set below UITableView Properties :
self.tableView.estimatedRowHeight = <minimum cell height>
self.tableView.rowHeight = UITableViewAutomaticDimension
For Swift i checked this answer in iOS 9.0 and iOS 11 also (Xcode 9.3)
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Here you need to add top, bottom, right and left constraints
For Swift 4.2
#IBOutlet weak var tableVw: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Set self as tableView delegate
tableVw.delegate = self
tableVw.rowHeight = UITableView.automaticDimension
tableVw.estimatedRowHeight = UITableView.automaticDimension
}
// UITableViewDelegate Method
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Happy Coding :)
This is simple when doing 2 things:
setting the automatic height
tableView.rowHeight = UITableView.automaticDimension
creating all TableViewCells with FULL constraints from top to bottom. The last element MUST define some bottom spacing to end the cell.
So the layout engine can compute the cell heigth and apply the value correctly.
Unfortunately, I am not sure what I was missing. The above methods don't work for me to get the xib cell's height or let the layoutifneeded()or UITableView.automaticDimension to do the height calculation. I've been searching and trying for 3 to 4 nights but could not find an answer.
Some answers here or on another post did give me hints for the workaround though. It's a stupid method but it works. Just add all your cells into an Array. And then set the outlet of each of your height constraint in the xib storyboard. Finally, add them up in the heightForRowAt method. It's just straight forward if you are not familiar with the those APIs.
Swift 4.2
CustomCell.Swift
#IBOutlet weak var textViewOneHeight: NSLayoutConstraint!
#IBOutlet weak var textViewTwoHeight: NSLayoutConstraint!
#IBOutlet weak var textViewThreeHeight: NSLayoutConstraint!
#IBOutlet weak var textViewFourHeight: NSLayoutConstraint!
#IBOutlet weak var textViewFiveHeight: NSLayoutConstraint!
MyTableViewVC.Swift
.
.
var myCustomCells:[CustomCell] = []
.
.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("CustomCell", owner: self, options: nil)?.first as! CustomCell
.
.
myCustomCells.append(cell)
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let totalHeight = myCustomCells[indexPath.row].textViewOneHeight.constant + myCustomCells[indexPath.row].textViewTwoHeight.constant + myCustomCells[indexPath.row].textViewThreeHeight.constant + myCustomCells[indexPath.row].textViewFourHeight.constant + myCustomCells[indexPath.row].textViewFiveHeight.constant
return totalHeight + 40 //some magic number
}
I use these
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
Try
override func viewWillAppear(animated: Bool) {
self.tableView.layoutSubviews()
}
I had the same problem and it works for me.
You should just set all constraints for TOP, BOTTOM and HEIGHT for each object on cell view/views and remove exists middle Y position if have. Because where you didn't this, puts artifacts on another views.
For objective c this is one of my nice solution. it's worked for me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [_nameArray objectAtIndex:indexPath.row];
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
We need to apply these 2 changes.
1)cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
2)return UITableViewAutomaticDimension;
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0
And don't forget to add botton constraints for label
I was just inspired by your solution and tried another way.
Please try to add tableView.reloadData() to viewDidAppear().
This works for me.
I think the things behind scrolling is "the same" as reloadData. When you scroll the screen, it's like calling reloadData() when viewDidAppear .
If this works, plz reply this answer so I could be sure of this solution.
I had also got this issue initially, I had resolved my issue from this code
try avoiding the use of self.tableView.reloadData() instead of this code for dynamic height
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
When using a static UITableView, I set all the values in the UILabels and then call tableView.reloadData().
What worked for me was creating a height constraint on my custom cell that I set at runtime (I've got an expand/collapse button in each cell).
Then in heightForRowAt in the parent, I had to do a combination of suggested answers:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if let cell = tableView.cellForRow(at: indexPath) as? GroupTableViewCell {
return cell.heightConstraint.constant
}
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 88.0
}
I use the already calculated height constraint constant where it's available and UITableView.automaticDimension otherwise. This was the only way to get the correct height and maintain the correct cell state when the cell gets recycled.
I hear it's considered bad practice to reference the cell itself inside heightForRowAt, but I don't see another way of doing it with custom cell objects with dynamic heights whilst keeping all constraints satisfied.
self.Itemtableview.estimatedRowHeight = 0;
self.Itemtableview.estimatedSectionHeaderHeight = 0;
self.Itemtableview.estimatedSectionFooterHeight = 0;
[ self.Itemtableview reloadData];
self.Itemtableview.frame = CGRectMake( self.Itemtableview.frame.origin.x, self.Itemtableview.frame.origin.y, self.Itemtableview.frame.size.width,self.Itemtableview.contentSize.height + self.Itemtableview.contentInset.bottom + self.Itemtableview.contentInset.top);
Set proper constraint and update delegate methods as:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
This will resolve dynamic cell height issue. IF not you need to check constraints.
Swift 5 Enjoy
tablev.rowHeight = 100
tablev.estimatedRowHeight = UITableView.automaticDimension
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tablev.dequeueReusableCell(withIdentifier: "ConferenceRoomsCell") as! ConferenceRoomsCell
cell.lblRoomName.numberOfLines = 0
cell.lblRoomName.lineBreakMode = .byWordWrapping
cell.lblRoomName.text = arrNameOfRooms[indexPath.row]
cell.lblRoomName.sizeToFit()
return cell
}

Resources