C'est donc un problème intéressant que nous avons trouvé avec UICollectionViewFlowLayout
sur iOS 10 (toujours un problème sur 11) et en utilisant UICollectionViewFlowLayoutAutomaticSize
pour leItemSize estimé.
Nous avons constaté que l'utilisation de UICollectionViewFlowLayoutAutomaticSize
pour l'estimationItemSize entraîne la vue supplémentaire du pied de page flottant au-dessus des quelques cellules du bas (rouge/rose est l'en-tête, vert est le pied de page).
Voici le code VC d'un exemple d'application:
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 {
}
Quelqu'un a-t-il réussi à faire fonctionner UICollectionViewFlowLayoutAutomaticSize sur iOS 10 avec des vues supplémentaires d'en-tête et de pied de page? Si j'ajoute une taille à l'estimationItemSize, cela semble fonctionner, mais je veux savoir s'il y a un bogue dans l'utilisation de la nouvelle fonctionnalité iOS 10 ou si je l'utilise incorrectement.
Le bogue déposé avec Apple a l'ID: 28843116
[~ # ~] mise à jour [~ # ~] : cela semble toujours être un problème sur 10.3 Beta 1
MISE À JOUR 2 : Cela semble toujours être un problème dans iOS 11 Beta 1
UICollectionViewFlowLayout
prend très bien en charge la disposition automatique des cellules, MAIS il ne la prend pas en charge pour les vues supplémentaires. Chaque fois que le code de disposition automatique met à jour le cadre de la cellule, il ne fait rien avec les en-têtes et les pieds de page. Vous devez donc indiquer à la mise en page qu'elle doit invalider les en-têtes et les pieds de page. Et il y a une méthode pour ça!
Vous devez remplacer la func invalidationContext(forPreferredLayoutAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes: UICollectionViewLayoutAttributes)
de UICollectionViewLayout
et y effectuer une invalidation de vue supplémentaire.
Exemple:
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
}
Dans l'exemple ci-dessus, j'utilise le contexte d'invalidation fourni par UICollectionViewFlowLayout
pour invalider la vue supplémentaire d'en-tête si la première cellule de la section a été invalidée. Vous pouvez également utiliser cette méthode pour l'invalidation du pied de page.
J'ai rencontré le même problème. UICollectionViewFlowLayoutAutomaticSize
ne fonctionne pas pour les vues supplémentaires. Utilisez le UICollectionViewDelegateFlowLayout
pour donner la taille explicitement. Il est préférable de calculer les tailles et d'utiliser les délégués car les calculs de taille automatiques provoquent parfois un retard.
utilisez les méthodes déléguées referenceSizeForHeaderInSection
et referenceSizeForFooterInSection
pour donner explicitement la taille de l'en-tête et du pied de page.