UITableViewCell 内的 UICollectionView -- 动态高度? [英] UICollectionView inside a UITableViewCell -- dynamic height?

查看:22
本文介绍了UITableViewCell 内的 UICollectionView -- 动态高度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的一个应用程序屏幕要求我们在 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 的大小,然后是集合视图的 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 的出口,使用 UICollectionViewFlowLayoutestimatedItemSize 为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆