I'm trying to put a uitableview within a uitableviewcell.The number of cells are dynamic, and the inner table view height should be the contentsize height. (Please refer to the images below) The first time the view loads it does not calculate the height of the cell correctly in that it only expands to the height of the label. After scrolling down and then back up so the cell reloads, it calculates the height correctly. Anyone have any ideas to fix this. I have included the cell's, the label's, and the inner tableview's constrains.
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority {
CGRect rect = self.answerOptionsTable.frame;
rect.size.height = MAXFLOAT;
self.answerOptionsTable.frame = rect;
[self.answerOptionsTable layoutIfNeeded];
CGSize returnedSize;
if ( self.answerOptionsTable.contentSize.height > self.lblQuestion.frame.size.height )
{
returnedSize = self.answerOptionsTable.contentSize;
}
else
{
returnedSize = self.lblQuestion.frame.size;
}
// add some padding
returnedSize.height += 20;
return returnedSize;
}
Cell Constraints
Table Constraints
Label Constraints
Initial draw
After reload of cell
Here is another example with smaller number of rows initial draw
Smaller number of rows after cell redraw
Related
I'm building a list view with self-sizing in my app using UICollectionView. Getting UICollectionViewFlowLayout to do a vertical list layout is a pain, so I'm writing my own UICollectionViewLayout subclass to do it.
My cells look a lot like regular table view cells - an image view on the left, a couple of labels vertically stacked in the center, and an accessory view on the right. The labels can wrap to a few lines and grow in font size according to the system font size setting, which is why they need to be self-sizing. Constraints are sensible - left to image view, image view to label, label to accessory, accessory to right, label to top and bottom.
To size my cells via preferredLayoutAttributesFittingAttributes, I need to get the desired height of the cell given the width of the collection view. I'd expect to use systemLayoutSizeFittingSize:horizontalPriority:verticalPriority: for this, passing a size like {desiredWidth, crazyLargeHeight}, UILayoutPriorityRequired for horizontal priority, and 1 for vertical priority. But the size I get back from systemLayoutFittingSize isn't sensible. The width is some previous width value from the cell (which doesn't necessarily match self.bounds.size.width or the passed-in layoutAttributes' size.width), and a height that works with that width. I also have tried passing a small height instead of a large one, and it still doesn't return the size it actually needs.
So how do I get the preferred height for the cell given a width value?
Sample code:
-(UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
UICollectionViewLayoutAttributes *result = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
CGSize exampleSize = CGSizeMake(layoutAttributes.size.width, 20);
CGSize size = [self systemLayoutSizeFittingSize:exampleSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:1];
result.size = size;
return result;
}
Turns out if you ask the cell's content view for a size instead of the cell itself, it works. And you have to give a sample height that is smaller than will be needed.
-(UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
UICollectionViewLayoutAttributes *result = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
CGSize exampleSize = CGSizeMake(layoutAttributes.size.width, 20); //magic number for example purposes...my cell will definitely be taller
CGSize size = [self.contentView systemLayoutSizeFittingSize:exampleSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:1];
result.size = size;
return result;
}
I'm guessing that the content view isn't pinned to the cell's bounds the way I expected. And this exact implementation will likely fall down if the content view is inset for some reason. But the key to solving this was the fact that having the cell contents pinned to the cell's content view does not mean that the cell itself will compute a size as you expect.
I have an UITableView (aka. ParentTableView) with multiple UITableViewCell's. Each UITableViewCell contains some labels and an UITableView (aka. ChildTableView).
The ChildTableView's rows have different amounts of UITableViewCells.
There is two things I need help to figure out.
1. The height of the ChildTableView should be the height of its contents. So there should be no scroll on this tableview. It's basically just a list.
2. Set the ParentTableView's row height to: (default height + ChildTableView's calculated height from question 1)
After tableView finishes loading cells ( gets its content ) update the Frame of the TableView with the Content Size.
so after reloadData:
var bounds = tableView.bounds
bounds.size.height = tableView.contentSize.height
// You can add anything to the height now with bounds.size.height += something
tableView.bounds = bounds
You can also explicitly disable the scrolling with scrollEnabled = false
This is my ViewController in the storyboard:
UIView (Controller)
-UIScrollView
--UIView
--UIView
--ContainerView
---UITableView (Embedded inside ContainerView)
The UITableView has dynamic prototypes.
My question is how do I change the UIScrollView and ContainerView's height to adapt to the UITableView's number of rows?
I want to be able to scroll down with my UIScrollView(not the UITableView's UIScrollView), when there are many rows inside the UITableView.
You can apply below logic to increase the height of scroll view.
height = Total number of rows (array or dictionary count) * your cell height (cell height should be static).
Using below calculation you will find the total height and set this height as a table height or scroll view height.
[scrollview setContentSize:CGMakeSize(scrollview.contentSize.width,tableView.frame.size.height)];
OR
[scrollview setContentSize:CGMakeSize(scrollview.contentSize.width,height)];
I hope this is work for you.
Thanks
Just update the contentSize of the UIScrollView every time there is a change in the number of rows.
Look at the example below:
- (void)updateScrollViewContentSize
{
float cellHeight = 40;
int numberOfRows = [noOfItemsInArray count];
float sizeOfContent = cellHeight * numberOfRows;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent);
}
I'm trying calculate the height of each cell in my table. Currently, I use this.
CGSize maximumSize = CGSizeMake(tableView.frame.size.width, UILayoutFittingCompressedSize.height);
CGFloat height = [offscreenCell.contentView systemLayoutSizeFittingSize:maximumSize].height;
return height;
The problem is that the cell has many labels with a date string label at the top of it and then multiple labels added below that listing the items for that date. This date label is being cut off for some reason in some of the cells. I think it might have to do with the label's string wrapping to a second line and the height not being calculated correctly.
Any ideas? Thank you.
Get a cell, set it's properties(date label, etc.) call layoutIfNeeded and then calculate this height:
MyCustomCell* cell = [myTableView dequeReusableCellWithIdentifier:#"CellId"];
for( NSString* text in arrayOfTexts )
{
[cell setDateLabelText:text];
[cell layoutIfNeeded];
CGSize maximumSize = CGSizeMake(tableView.frame.size.width, UILayoutFittingCompressedSize.height);
CGFloat height = [offscreenCell.contentView systemLayoutSizeFittingSize:maximumSize].height;//now store this height and use it in height for row at index path
}
I have some dynamic text content that should grow the cell vertically and I am doing it by calculating the height and returning that for the table cell. The table cell grows in size fine but the issue is growing the UIView inside the cell.
I set the height of the UIView inside the cell using the same method of calculating height using the following code but the UIView does not grow even after setting its frame. So below the businessDescriptionTextView is a Label and container is a UIView inside the cell. I am setting both of them and the getHeightBusinessDescription does return the correct height but for some reason it does not redraw
cell.businessDescriptionTextView.text = self.dealLocation.company.description;
cell.businessDescriptionTextView.lineBreakMode = NSLineBreakByWordWrapping;
cell.businessDescriptionTextView.numberOfLines = 0;
[cell.businessDescriptionTextView sizeToFit];
CGRect frame = cell.container.layer.frame;
frame.size.height = [self getHeightBusinessDescription] + 50;
cell.container.layer.frame = frame;
I have tried setNeedsDisplay on cell.container cell.businessDescriptionTextView and still no luck. I also tried the table reload
[self.tableView reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone];
With the beginUpdates and endUpdates right after I set the frame size and still nothing happened.