ios - ¿Por qué UICollectionView registra un error cuando las celdas están en pantalla completa?
objective-c ios7 (5)
Tengo un UICollectionViewController
utilizando un UICollectionViewFlowLayout
donde mi itemSize
es el tamaño de la UICollectionView
. Básicamente, este es un diseño de línea de celdas donde cada celda está en pantalla completa y se desplaza horizontalmente.
En mi subclase UICollectionViewFlowLayout
, he invalidado prepareLayout
siguiente manera:
- (void)prepareLayout {
self.itemSize = self.collectionView.frame.size;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.collectionView.pagingEnabled = YES;
self.minimumLineSpacing = 0.0;
self.minimumInteritemSpacing = 0.0;
self.sectionInset = UIEdgeInsetsZero;
self.footerReferenceSize = CGSizeZero;
self.headerReferenceSize = CGSizeZero;
}
El UICollectionViewController
es muy básico y devuelve 10 elementos en una sección. He incluido un proyecto de muestra en GitHub para más detalles.
Todo parece estar configurado correctamente. Se ve bien en el simulador y en el dispositivo pero, cuando se muestra la vista de colección, hay un error registrado en la consola:
the behavior of the UICollectionViewFlowLayout is not defined because: the item height must be less that the height of the UICollectionView minus the section insets top and bottom values.
Tenga en cuenta también que el controlador de vista de colección en mi ejemplo está en un controlador de navegación y aunque no parece particularmente necesario en el ejemplo, en mi caso del mundo real necesito la vista de colección en un controlador de navegación.
Este problema se me ocurrió en las pantallas 3x (a saber, el iPhone 6 Plus). Resultó que al motor de autoajuste no le gustaban los valores de punto flotante infinito (como .33333333), por lo que mi solución fue reducir la altura de retorno. sizeForItemAt:indexPath:
return CGSize(width: preferredWidth, height: floor(preferredHeight))
Hay una propiedad en UIViewController
- UIViewController
automaticallyAdjustsScrollViewInsets
- que por defecto es YES
. Esto significa que cuando un UIViewController
tiene un UIScrollView
en su jerarquía de vistas, lo que se UICollectionViewController
un UICollectionViewController
, la propiedad contentInset
de esa vista de desplazamiento se ajusta automáticamente para tener en cuenta las áreas de pantalla consumidas por la barra de estado, la barra de navegación, la barra de herramientas o la barra de pestañas .
La documentación para esa propiedad establece:
automaticAdjustsScrollViewInsets
Especifica si el controlador de vista debe ajustar automáticamente sus inserciones de vista de desplazamiento.
@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
Discusión
El valor predeterminado es SÍ, lo que permite al controlador de vista ajustar sus inserciones de vista de desplazamiento en respuesta a las áreas de pantalla consumidas por la barra de estado, la barra de navegación y la barra de herramientas o la barra de pestañas. Establézcalo en NO si desea administrar los ajustes de inserción de la vista de desplazamiento, por ejemplo, cuando hay más de una vista de desplazamiento en la jerarquía de vistas.
La solución es establecer automaticallyAdjustsScrollViewInsets
UICollectionViewController
los UICollectionViewController
a NO
en algún lugar de su subclase UICollectionViewController
, como en viewDidLoad
:
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
}
He puesto un proyecto de ejemplo en GitHub que ilustra este problema y esta solución. Hay dos ramas: with_error
y fixed_error
. Aquí hay una diferencia del cambio en GitHub .
Tuve un problema similar.
Después de la celda de carga que es de ancho completo y algo de altura de la pantalla. en alguna condición cambié la altura de la celda y luego estaba recibiendo el mismo error
para arreglar esto
solía
func updateHeightPerRatio(with image:UIImage) {
let ratio = collectionView.bounds.width / image.size.width
constHeightCollectionView .constant = ceil(image.size.height * ratio)
collectionView.reloadData()
collectionView.performBatchUpdates({
collectionView.layoutIfNeeded()
}) { (completed) in
self.collectionView.reloadData()
self.layoutIfNeeded()
}
}
La solución es volver a cargar los datos y luego realizar la actualización por lotes con esa vista de colección volver a calcular los marcos. después de que vuelva a cargar la vista de colección, aplicará los marcos calculados a la celda
Y ahora no hay registro para el problema ahora.
Espero que sea de ayuda
ios 10: la vista superior no estaba conectada a la salida de la vista
Actualización de iOS 11: automaticallyAdjustsScrollViewInsets
está en desuso en iOS 11.0.
Apple recomienda usar el método contentInsetAdjustmentBehavior
UIScrollView
en su lugar. Establecí este valor en .never
y el error desapareció. También puede establecer esta propiedad en Interface Builder.