简体   繁体   English

自定义集合视图布局的动态单元格高度

[英]Dynamic Cell Height for Custom Collection View Layout

I have a collection view which makes use of a custom layout. 我有一个使用自定义布局的集合视图。 I'm trying to calculate the height dynamically, but the problem is sizeForItemAt:indexPath is called before cellForItemAt:indexPath. 我正在尝试动态计算高度,但是问题是在cellForItemAt:indexPath之前调用了sizeForItemAt:indexPath。

My cells get loaded in cellForItemAt. 我的单元格加载到cellForItemAt中。 But since sizeForItemAt is called before cellForItemAt, then I can't use my calculated height. 但是由于sizeForItemAt在cellForItemAt之前被调用,所以我不能使用计算出的高度。

I know with Apple's FlowLayout I can just set the estimatedItemSize for the layout. 我知道使用Apple的FlowLayout可以只为布局设置estimateItemSize。 I'm not sure how to do it with a custom layout. 我不确定如何使用自定义布局。

Please advise. 请指教。 Thank you! 谢谢!

I had the same problem, my app uses custom layout with dynamic height. 我遇到了同样的问题,我的应用程序使用具有动态高度的自定义布局。 I found that with custom layout that doesn't extend UICollectionViewFlowLayout or any other default layout, dynamic height will not work because as per Apple documentation (and like you probably noticed) with a completely custom layout you have to predefine all the cells X, Y, width, height before the cell load and before you even have data. 我发现,使用不会扩展UICollectionViewFlowLayout或其他任何默认布局的自定义布局,动态高度将不起作用,因为根据Apple文档(以及您可能注意到的那样),使用完全自定义布局的Apple必须预先定义所有单元格X,Y ,宽度,高度, 然后再加载单元格甚至没有数据。 I changed my custom layout to subclass UICollectionViewFlowLayout and implemented UICollectionViewDelegateFlowLayout . 我将自定义布局更改为UICollectionViewFlowLayout子类,并实现了UICollectionViewDelegateFlowLayout When this method is called the cell did not load yet but the cell's data is available since I know what the cell should look like (assuming you are using cell prototypes) I could calculate the cell width and height using its data and index, something like this: 调用此方法时,单元尚未加载,但是单元的数据可用,因为我知道单元的外观(假设您使用的是单元原型),我可以使用其数据和索引来计算单元的宽度和高度,例如这个:

func collectionView(_ collectionView: UICollectionView, 
         layout collectionViewLayout: UICollectionViewLayout, 
             sizeForItemAt indexPath: IndexPath) -> CGSize {
   // get the cell's data 
   if let data = self.fetchedResultsController.fetchedObjects![indexPath.row] as? YourDataType {
      // carculate the cell width according to cell position
      let cellWidth = carculateCellWidth(indexPath.row) 
      var cellHeight : CGFloat = 0
      // assuming the cell have a label, set the label to have the same attributes as set in the storyboard or set programmatically
      let label = UILabel()  
      label.numberOfLines = 0
      label.font = UIFont.preferredFont(forTextStyle: .subheadline)
      label.text = data.text
      // carculate the height of the cell, assuming here the label width equal the cell width minus 10px left and right padding. 
      cellHeight += label.systemLayoutSizeFitting(CGSize(width:cellWidth-20, height: CGFloat(Float.greatestFiniteMagnitude))).height
      return CGSize(width: cellWidth, height: cellHeight)
   }
   return .zero
}

This is not a very elegant solution but it works. 这不是一个非常优雅的解决方案,但它可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM