我正在尝试使用几个部分实现一个集合高度取决于其内容的集合(多行UILabel)。
viewDidLoad中:
self.collectionView.delegate = self
self.collectionView.dataSource = self
self.collectionView.registerNib(UINib(nibName: "CustomCell", bundle: nil),
forCellWithReuseIdentifier: "collectionCell")
self.collectionView.registerNib(UINib(nibName: "CustomHeader", bundle: nil),
forSupplementaryViewOfKind: UICollectionElementKindSectionHeader,
withReuseIdentifier: "header")
let flowLayout = CustomLayout()
flowLayout.estimatedItemSize = CGSizeMake(300, 20)
flowLayout.headerReferenceSize = CGSizeMake(300, 24)
self.collectionView.collectionViewLayout = flowLayout
cellForItemAtIndexPath:
let cell: CustomCell = collectionView.dequeueReusableCellWithReuseIdentifier("collectionCell", forIndexPath: indexPath) as! CustomCell
let section = sections[indexPath.section]
let text = data[section]![indexPath.row]
cell.configureWithText(text, screenWidth: self.view.frame.width, numberOfColumns: numberOfColumns)
return cell
viewForSupplementaryElementOfKind:
var reusableView = UICollectionReusableView()
if kind == UICollectionElementKindSectionHeader {
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader,
withReuseIdentifier: "header",
forIndexPath: indexPath)
(headerView as! CustomHeader).configureWithText(sections[indexPath.section], width: self.view.frame.width)
reusableView = headerView
}
return reusableView
CustomCell:
@IBOutlet weak var textLabel: UILabel!
var height: CGFloat!
var width: CGFloat!
func configureWithText(text: String, screenWidth: CGFloat, numberOfColumns: CGFloat) {
let cellWidth = (screenWidth - 40) / numberOfColumns
self.contentView.frame.size = CGSizeMake(cellWidth, 300)
self.textLabel.text = text
self.textLabel.sizeToFit()
self.width = cellWidth
self.height = self.textLabel.frame.height + 16
print(self.textLabel.frame.height)
}
override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
super.preferredLayoutAttributesFittingAttributes(layoutAttributes)
layoutAttributes.frame = CGRectMake(layoutAttributes.frame.origin.x, layoutAttributes.frame.origin.y, width, height)
return layoutAttributes
}
CustomHeader:
@IBOutlet weak var textLabel: UILabel!
var width: CGFloat!
func configureWithText(text: String, width: CGFloat) {
self.textLabel.text = text
self.width = width
}
override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
super.preferredLayoutAttributesFittingAttributes(layoutAttributes)
layoutAttributes.frame = CGRectMake(layoutAttributes.frame.origin.x, layoutAttributes.frame.origin.y, width, 24)
return layoutAttributes
}
在我的自定义布局(流程布局)中,shouldInvalidateLayoutForBoundsChange始终返回true,我在旋转的collectionView上调用reloadData()(viewWillTransitionToSize)。
假设我以纵向方式启动应用程序并旋转到横向,一切正常。但现在,如果我回到肖像画,我会得到一个例外,如下所示:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'layout attributes for supplementary item at index path (<NSIndexPath: 0xc000000000000116> {length = 2, path = 1 - 0}) changed from <UICollectionViewLayoutAttributes: 0x7fc0a2ceb430> index path: (<NSIndexPath: 0xc000000000000116> {length = 2, path = 1 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 250; 768 24); zIndex = 10; to <UICollectionViewLayoutAttributes: 0x7fc0a2cd90e0> index path: (<NSIndexPath: 0xc000000000000116> {length = 2, path = 1 - 0}); element kind: (UICollectionElementKindSectionHeader); frame = (0 407; 768 24); zIndex = 10; without invalidating the layout'