UICollectionView estimatedItemSize布局属性已更改,但未使布局无效

时间:2016-03-31 20:47:04

标签: ios uicollectionview

我正在尝试使用几个部分实现一个集合高度取决于其内容的集合(多行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'

0 个答案:

没有答案