Before iOS 15 after I made
self.tableView.beginUpdates()
self.tableView.endUpdates()
method heightForRowAtindexPath was called and my cell height changed without reloading data in the cell. Now in iOS 15 this not works! How can I force reload tableview cell height without reloading data in this cell?
I have already solved the problem. Apparently, Apple made a change in the way updates are processed and cell sizes are adjusted.
As the "hidden" cell is left at 0, when sending the beginUpdate, it only processes the cells that have a value greater than 0, so that is why it no longer adjusts them.
What you need to do is change the value of 0, returned for hidden cells, to 0.01, and you're done!
I hope this solution works the same for me.
Found a solution:
In heightForRowAtindexPath method return for resizable cell UITableView.automaticDimension instead of size
Inside my custom tableView cell I added height constraint to my container view (in my case this is webView)
In a place where I get cell size and need to update height (for me after webView content was loaded), I update height contraint:
.
cell.heightContraint.constant = size
self.tableView.beginUpdates()
self.tableView.endUpdates()
So the cell is autoresizable now with UITableView.automaticDimension height and, of course, your view/container view should have top and bottom constraints equal to cell`s top and bottom constraints
Related
I'm displaying information fetched from a server on tableview. My tableview cell view has two vertical stackviews placed horizontally in a content view. Each stackview has 6 items and depending on data I'm hiding and showing the stackview item and setting the stackview and content view height depending on content of stackview visible items. This is all working fine and the tableview is also looking good.
Now I have a feature to delete tableview rows on swipe of a tableview row. So after deleting any row and reloading tableview cells, tableview cell height is not getting set and shrinks.
Can anyone help me with how do I update tableview height after each reload? I've tried all possible solutions but none of them worked to me.
Try the following, in your viewDidLoad set:
tableView.estimatedRowHeight = 60 // this is an estimation but try and get it close to what the actual height may be
tableView.rowHeight = UITableViewAutomaticDimension
Then in the tableView heightForRowAt indexPath return this:
return UITableViewAutomaticDimension
I'm trying to use a stackview inside a tableview cell. My stack view has two labels aligned horizontally. I've added a size class override in IB to align the labels vertically for compact width.
The alignment of the label does change as expected but the height of the cells is incorrect until I scroll cells out and back in.
My table view specifies to calculate the height of the cell using:
// Automatic row height calculation
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 68.0 // set to whatever your "average" cell height is
So, in an iPhone SE, I want the labels side by side in landscape but one on top of the other in portrait. If I start my app in portrait mode the labels are as expected but when I rotate to landscape they move to side by side but the cell still has the height as in portrait. If I scroll cells off the screen then the cell height is corrected.
What am I missing?
Please help.
Thanks.
OK. Looks like there may be a legitimate bug but I continued to do some digging because stackviews are so much easier to work with. And, finally, got an answer in https://www.raywenderlich.com.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
DispatchQueue.main.async {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
Yeap!, wrapping begin/end update calls asynchronously in the main queue allows the cell's height to get properly calculated. Never would have thought of it since traitCollectionDidChange() is already running in the main queue.
See Using uistackviews in uitableviewcell for details.
Thanks, Jerry!
I have an UITableViewCell with UILabel which correctly resizes its height according to text length. To accomplish this I have correctly set AutoLayout constraints and specified
tableView.rowHeight = UITableViewAutomaticDimension
The problem I am having is when the test of the UILabel gets longer after pressing a UIButton - READ MORE, in the cell itself. I programmatically add text to the UILabel and I expect the cell height to grow. I have added:
self.layoutIfNeeded()
self.updateConstraints()
in the cell, but it is not working. Cell stays same height.
I have also forced a reload of the cell row in the delegate UIViewController
but it is not working either. Am I missing something basic here?
EDIT: The question differ from other similar questions, because I'd like the answer to avoid having to calculate the height manually. Since AutoLayout is perfectly able to calculate correct dynamic height at first load, I guess there should be a way to make it redraw the cell once the text in the label gets longer, without the need of performing manual calculation to estimate row height.
Get the Label height dynamically and set the tableviewcell height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Calculate the Label height and add it to default height of the cell
}
I have found a solution that works, after updating the UILabel content I am calling:
UIView.animateWithDuration(0.3) {
cell.contentView.layoutIfNeeded()
}
To update cell constraints. And then to resize the cell height:
tableView.beginUpdates()
tableView.endUpdates()
I will wait to accept this answer to see if someone else will answer a more elegant solution though.
A lot of the solutions I've seen here include changing the cell's background to an image and using sections for rows rather than just rows themselves. I'm looking to have only two sections and have each cell expand in height on tap, so neither of those solutions would work.
I saw one solution includes setting the frame of the cell in the layoutSubviews() function like so:
override func layoutSubviews() {
super.layoutSubviews()
self.frame = CGRectOffset(self.frame, 0, 10);
}
When I do this however, it only gives margin to one cell and that's only when I tap on the cell.
Is there a surefire way to add spacing in between UITableViewCells without being hacky and breaking the cell layouts in the process?
I did this yesterday pretty easily with auto layout.
I set the background of the cell and it's content view to clear, then I created a new view and setup constraints all around it and put my labels inside of it. The height changes dynamically based on the label so I needed to use UITableViewAutomaticDimension for the row height and give it an estimated row height as well.
I don't see why this wouldn't work for expanding it on a tap as well, you just might have to reload the cell.
make the cell and it's contentView transparent
contentView addSubview customContentView and layout your cell on customContentView
customContentView pin to contentView top leading trailing with offset 0 but pin to bottom with offset 10 //the margin height
I'm hiding rows that are completed in a collectionView.
I call cell.hidden = isCellHidden in cellForItemAtIndexPath when needed.
After I hide 10 rows there is plenty of empty space left and I'd like to trim down the size of the collectionView to only fit the rows that are not hidden.
The collectionView's design is kind of like a tableView.
I know with the tableView all I had to do to achieve this is set:
func section1VisibilityButton(sender: UIButton){
isCellHidden = !isCellHidden
self.tableView.reloadData()
self.tableView.contentSize.height = CGFloat(500)
}
with a collectionView when I try this it will resize it correctly but as soon as I try to scroll down it resizes itself back to the original height including the cells hidden (the cells layer is still hidden but there's tons of empty space bellow the last visible row as if they were visible)
For your issue, there are two options to change the frame of your collectionView/tableView.
If you are using autolayout, you need to create IBOutlet of bottom constraint or IBOutlet of constant height constraint of your tableView (anyone of these constraints, which you are using).
After reload tableView data you need to update constraint by calculating its height.
Suppose you are using constant height constraint and your calculated height is 150(e.g. 3 rows and 50 height of each row).
constraintTableViewHeight.constant = 150;//this will change height
self.view.layoutIfneed(); // this will apply updated constraints to whole view
If you are not using autolayout, you can manually change the height by changing tableView.frame property.