custom - iOS 10/11 UICollectionViewFlowLayout usando UICollectionViewFlowLayoutAutomaticSize da como resultado una vista suplementaria de pie de página desalineada
uicollectionview layout (2)
Así que este es un problema interesante que encontramos con UICollectionViewFlowLayout
en iOS 10 (todavía es un problema en 11) y que usa UICollectionViewFlowLayoutAutomaticSize
para el valor estimado del artículo.
Hemos encontrado que el uso de UICollectionViewFlowLayoutAutomaticSize
para el valor estimado de UICollectionViewFlowLayoutAutomaticSize
en la vista suplementaria del pie de página flotando sobre las pocas celdas inferiores. (Rojo / Rosa es el encabezado, Verde es el pie de página).
Aquí está el código VC de una aplicación de muestra:
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 {
}
¿Alguien ha logrado que UICollectionViewFlowLayoutAutomaticSize funcione en iOS 10 con vistas adicionales de encabezado y pie de página? Si agrego un tamaño al estimadoItemSize, entonces parece que funciona, pero quiero saber si hay un error en el uso de la nueva función iOS 10 o si lo estoy usando incorrectamente.
El error presentado con Apple tiene el ID: 28843116
ACTUALIZACIÓN : Esto todavía parece ser un problema en 10.3 Beta 1
ACTUALIZACIÓN 2 : Esto todavía parece ser un problema en iOS 11 Beta 1
Me encontré con el mismo problema. UICollectionViewFlowLayoutAutomaticSize
no funciona para vistas suplementarias. Use UICollectionViewDelegateFlowLayout
para dar el tamaño explícitamente. Es mejor calcular los tamaños y utilizar delegados, ya que los cálculos automáticos de tamaño causan retrasos, a veces.
use los métodos de delegación referenceSizeForHeaderInSection
y referenceSizeForFooterInSection
para dar el encabezado y el tamaño del pie de página explícitamente.
UICollectionViewFlowLayout
admite el diseño automático de celdas muy bien, PERO no lo admite para vistas suplementarias. Cada vez que el código de diseño automático actualiza el marco de la celda, no hace nada con los encabezados y pies de página. Por lo tanto, debe indicar al diseño que debe invalidar los encabezados y pies de página. ¡Y hay un método para esto!
Debe anular la func invalidationContext(forPreferredLayoutAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes: UICollectionViewLayoutAttributes)
y realizar una invalidación de vista complementaria en él.
Ejemplo:
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
}
En el ejemplo anterior, estoy usando el contexto de invalidación provisto por UICollectionViewFlowLayout
para invalidar la vista suplementaria del encabezado si se invalida la primera celda de la sección. También puede utilizar este método para la invalidación de pie de página.