UIColViewView里面的UIColViewView - 动态高度? [英] 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?
推荐答案
正确的答案是是,你 CAN 这样做。
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
给定以下结构:
TableView
TableView
TableViewCell
TableViewCell
CollectionView
CollectionView
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
CollectionViewCell
[...可变数量的单元格或不同的单元格大小]
[...variable number of cells or different cell sizes]
解决方案是告诉自动布局首先计算collectionViewCell大小,然后是集合视图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 是神奇的。它有一个outletView的插座,使用 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;
}
CREDIT: @ rbarbera 帮助解决了这个问题
CR @rbarbera helped to sort this out
这篇关于UIColViewView里面的UIColViewView - 动态高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!