UITableViewCell 内的 UICollectionView - 动态高度? [英] UICollectionView inside a UITableViewCell -- dynamic height?
问题描述
我们的一个应用程序屏幕要求我们在 UITableViewCell
内放置一个 UICollectionView
.此 UICollectionView
将具有动态数量的项目,从而产生必须动态计算的高度.但是,我在尝试计算嵌入式 UICollectionView
的高度时遇到了问题.
One of our application screens requires us to place a UICollectionView
inside of a UITableViewCell
. This UICollectionView
will have a dynamic number of items, resulting in a height which must be calculated dynamically as well. However, I am running into problems trying to calculate the height of the embedded UICollectionView
.
我们的总体 UIViewController
是在 Storyboards 中创建的,并且确实使用了自动布局.但是,我不知道如何根据 UICollectionView
的高度动态增加 UITableViewCell
的高度.
Our overarching UIViewController
was created in Storyboards and does make use of auto layout. But, I don't know how to dynamically increase the height of the UITableViewCell
based on the height of the UICollectionView
.
任何人都可以就如何做到这一点提供一些提示或建议吗?
Can anyone give some tips or advice on how to accomplish this?
推荐答案
正确答案是YES,你可以这样做.
The right answer is YES, you CAN do this.
几周前我遇到了这个问题.它实际上比你想象的要容易.将您的单元格放入 NIB(或故事板)并固定它们以让自动布局完成所有工作
I came across this problem some weeks ago. It is actually easier than you may think. Put your cells into NIBs (or storyboards) and pin them to let auto layout do all the work
给定以下结构:
表格视图
TableViewCell
TableViewCell
集合视图
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
[...可变数量的单元格或不同的单元格大小]
[...variable number of cells or different cell sizes]
解决方案是告诉自动布局首先计算 collectionViewCell 大小,然后是 collection view contentSize,并将其用作单元格的大小.这是施展魔法"的 UIView 方法:
The solution is to tell auto layout to compute first the collectionViewCell sizes, then the collection view contentSize, and use it as the size of your cell. This is the UIView method that "does the magic":
-(void)systemLayoutSizeFittingSize:(CGSize)targetSize
withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority
verticalFittingPriority:(UILayoutPriority)verticalFittingPriority
您必须在此处设置 TableViewCell 的大小,在您的情况下是 CollectionView 的 contentSize.
You have to set here the size of the TableViewCell, which in your case is the CollectionView's contentSize.
在 CollectionViewCell 处,您必须在每次更改模型时告诉单元格进行布局(例如:您设置带有文本的 UILabel,然后单元格必须再次进行布局).
At the CollectionViewCell you have to tell the cell to layout each time you change the model (e.g.: you set a UILabel with a text, then the cell has to be layout again).
- (void)bindWithModel:(id)model {
// Do whatever you may need to bind with your data and
// tell the collection view cell's contentView to resize
[self.contentView setNeedsLayout];
}
// Other stuff here...
TableViewCell
TableViewCell 具有魔力.它有一个到您的 collectionView 的出口,使用 UICollectionViewFlowLayout 的 estimatedItemSize 启用 collectionView 单元格的自动布局.
TableViewCell
The TableViewCell does the magic. It has an outlet to your collectionView, enables the auto layout for collectionView cells using estimatedItemSize of the UICollectionViewFlowLayout.
然后,诀窍是在 systemLayoutSizeFittingSize... 方法中设置 tableView 单元格的大小.(注意:iOS8 或更高版本)
Then, the trick is to set your tableView cell's size at the systemLayoutSizeFittingSize... method. (NOTE: iOS8 or later)
注意:我尝试使用 tableView -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
的委托单元格的高度方法.但是 为时已晚 用于自动布局系统计算 CollectionView contentSize,有时您可能会发现调整大小错误的单元格.
NOTE: I tried to use the delegate cell's height method of the tableView -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
.but it's too late for the auto layout system to compute the CollectionView contentSize and sometimes you may find wrong resized cells.
@implementation TableCell
- (void)awakeFromNib {
[super awakeFromNib];
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
// Configure the collectionView
flow.minimumInteritemSpacing = ...;
// This enables the magic of auto layout.
// Setting estimatedItemSize different to CGSizeZero
// on flow Layout enables auto layout for collectionView cells.
// https://developer.apple.com/videos/play/wwdc2014-226/
flow.estimatedItemSize = CGSizeMake(1, 1);
// Disable the scroll on your collection view
// to avoid running into multiple scroll issues.
[self.collectionView setScrollEnabled:NO];
}
- (void)bindWithModel:(id)model {
// Do your stuff here to configure the tableViewCell
// Tell the cell to redraw its contentView
[self.contentView layoutIfNeeded];
}
// THIS IS THE MOST IMPORTANT METHOD
//
// This method tells the auto layout
// You cannot calculate the collectionView content size in any other place,
// because you run into race condition issues.
// NOTE: Works for iOS 8 or later
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority {
// With autolayout enabled on collection view's cells we need to force a collection view relayout with the shown size (width)
self.collectionView.frame = CGRectMake(0, 0, targetSize.width, MAXFLOAT);
[self.collectionView layoutIfNeeded];
// If the cell's size has to be exactly the content
// Size of the collection View, just return the
// collectionViewLayout's collectionViewContentSize.
return [self.collectionView.collectionViewLayout collectionViewContentSize];
}
// Other stuff here...
@end
TableViewController
记得在你的 TableViewController 中为 tableView 单元格启用自动布局系统:
TableViewController
Remember to enable the auto layout system for the tableView cells at your TableViewController:
- (void)viewDidLoad {
[super viewDidLoad];
// Enable automatic row auto layout calculations
self.tableView.rowHeight = UITableViewAutomaticDimension;
// Set the estimatedRowHeight to a non-0 value to enable auto layout.
self.tableView.estimatedRowHeight = 10;
}
信用:@rbarbera 帮助解决了这个问题
CR @rbarbera helped to sort this out
这篇关于UITableViewCell 内的 UICollectionView - 动态高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!