使用UICollectionViewFlowLayoutAutomaticSize的iOS 10/11 UICollectionViewFlowLayout导致页脚补充视图未对齐

所以这是我们在iOS 10上发现的UICollectionViewFlowLayout (仍然是11的问题)和使用UICollectionViewFlowLayoutAutomaticSize为estimatedItemSize发现的一个有趣问题。

我们发现使用UICollectionViewFlowLayoutAutomaticSize为estimatedItemSize导致在底部几个单元格上方浮动的页脚补充视图。(红色/粉红色是标题,绿色是页脚。)

UICollectionViewFlowLayoutAutomaticSize问题 在此处输入图像描述

以下是示例应用的VC代码:

 import UIKit class ViewController: UIViewController { // MARK: Properties let texts: [String] = [ "This is some text", "This is some more text", "This is even more text" ] // MARK: Outlets @IBOutlet var collectionView: UICollectionView! { didSet { self.collectionView.backgroundColor = .orange } } // MARK: Lifecycle override func viewDidLoad() { super.viewDidLoad() // Layout let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical if #available(iOS 10.0, *) { layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize } else { layout.estimatedItemSize = CGSize(width: self.collectionView.bounds.width, height: 50) } self.collectionView.collectionViewLayout = layout // Register Cells self.collectionView.register(UINib(nibName: "TextCell", bundle: nil), forCellWithReuseIdentifier: String(describing: TextCell.self)) self.collectionView.register(UINib(nibName: "SectionHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: String(describing: SectionHeader.self)) self.collectionView.register(UINib(nibName: "SectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: String(describing: SectionFooter.self)) self.collectionView.reloadData() } } // MARK: - UICollectionViewDelegateFlowLayout Methods extension ViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { return CGSize(width: self.collectionView.bounds.width, height: 90) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { return CGSize(width: self.collectionView.bounds.width, height: 90) } } // MARK: - UICollectionViewDataSource Methods extension ViewController: UICollectionViewDataSource { public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.texts.count } func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TextCell.self), for: indexPath) if let textCell = cell as? TextCell { let text = self.texts[indexPath.row] textCell.configure(text: text) } return cell } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { switch kind { case UICollectionElementKindSectionHeader: return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionHeader.self), for: indexPath) case UICollectionElementKindSectionFooter: return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionFooter.self), for: indexPath) default: return UICollectionReusableView() } } } // MARK: - UICollectionViewDelegate Methods extension ViewController: UICollectionViewDelegate { } 

有没有人设法让UICollectionViewFlowLayoutAutomaticSize在iOS 10上使用补充页眉和页脚视图? 如果我向estimatedItemSize添加一个大小,那么它似乎可以工作,但我想知道使用新的iOS 10function是否存在错误,或者我是否正确使用它。

向Apple提交的错误ID为: 28843116

更新 :这似乎仍然是10.3 Beta 1的问题

更新2 :这似乎仍然是iOS 11 Beta 1中的一个问题

UICollectionViewFlowLayout非常支持单元格的自动布局, 它不支持补充视图。 每次自动布局代码更新单元格的框架时,它都不会对页眉和页脚做任何处理。 因此,您需要告诉布局它应该使页眉和页脚无效。 并且有一种方法可以做到这一点!

您应该覆盖UICollectionViewLayoutfunc invalidationContext(forPreferredLayoutAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes: UICollectionViewLayoutAttributes)并在其中执行补充视图失效。

例:

 override open func invalidationContext(forPreferredLayoutAttributes preferred: UICollectionViewLayoutAttributes, withOriginalAttributes original: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext { let context: UICollectionViewLayoutInvalidationContext = super.invalidationContext( forPreferredLayoutAttributes: preferred, withOriginalAttributes: original ) let indexPath = preferred.indexPath if indexPath.item == 0 { context.invalidateSupplementaryElements(ofKind: UICollectionElementKindSectionHeader, at: [indexPath]) } return context } 

在上面的示例中,我使用UICollectionViewFlowLayout提供的失效上下文,如果节中的第一个单元格无效,则使标题补充视图无效。 您也可以将此方法用于页脚失效。

我遇到了同样的问题。 UICollectionViewFlowLayoutAutomaticSize不适用于补充视图。 使用UICollectionViewDelegateFlowLayout显式提供大小。 最好计算尺寸并使用代表作为自动尺寸计算有时会导致滞后。

使用referenceSizeForHeaderInSectionreferenceSizeForFooterInSection委托方法显式地给出页眉和页脚大小。