在设置好数据之后调整UICollectionView单元的大小

我的UICollectionView单元格包含带有多行文本的UILabels 。 我不知道UICollectionViewCellsheight ,直到在UILabel上设置文本。

 -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath; 

是我看到的大小UICollectionViewCells的初始方法,但是这被称为之前的单元格创build的UIStoryboard 。 有没有一种方法来布局集合和大小的单元格后,他们已经被渲染,我知道单元格的实际大小?

我想你正在寻找可以调用你的UICollectionView的.collectionViewLayout属性的invalidateLayout方法。 这个方法重新生成你的布局,在你的情况下,也意味着调用-collectionView: layout: sizeForItemAtIndexPath:这是反映你想要的项目大小的正确位置。 Jirune指出了如何计算它们的正确方向。

可以在这里find使用invalidateLayout的例子。 另请参阅该方法的UICollectionViewLayout文档:

使当前布局无效并触发布局更新。

讨论:

您可以随时调用此方法更新布局信息。 此方法使集合视图本身的布局无效并立即返回。 因此,您可以从相同的代码块多次调用此方法,而不会触发多个布局更新。 实际布局更新在下一个视图布局更新周期中发生。

编辑:

对于包含自动布局约束的故事板集合视图,您需要重写UIViewController viewDidLayoutSubviews方法,并在此方法中调用invalidateLayout集合视图布局。

 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; [yourCollectionView.collectionViewLayout invalidateLayout]; } 

嘿在上面的delegate方法本身,您可以使用下面的棘手方式计算UILabel大小,并返回基于该计算的UICollectionViewCell size

  // Calculate the expected size based on the font and // linebreak mode of your label CGSize maximumLabelSize = CGSizeMake(9999,9999); CGSize expectedLabelSize = [[self.dataSource objectAtIndex:indexPath.item] sizeWithFont:[UIFont fontWithName:@"Arial" size:18.0f] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping]; 

子类UICollectionViewCell并重写像这样的layoutSubviews

在此您将锚点的细胞前导和后沿锚定到collectionView

 override func layoutSubviews() { super.layoutSubviews() self.frame = CGRectMake(0, self.frame.origin.y, self.superview!.frame.size.width, self.frame.size.height) } 
 - (void)viewDidLoad { self.collectionView.prefetchingEnabled = NO; } 

在iOS 10中, prefetchingEnabled默认为YES 。 当YES ,收集视图会在要显示的时间之前请求单元格。 它导致在iOS 10中崩溃