ios6 - repisas - estantes para libros de madera
Crear un estante de libros utilizando UICollectionView (1)
Voy a crear un estante de libros en uno de mis proyectos. El requisito básico es el siguiente:
- similar a la estantería iBooks
- Apoya bien ambas orientaciones
- Soporta bien todo tipo de dispositivos iOS (diferentes resoluciones)
- soporta borrar e insertar elementos
- Soporta la reordenación de los artículos mediante un gesto de pulsación larga.
- muestra un logo oculto cuando la primera fila se tira hacia abajo
El UICollectionView es la primera opción que se me ocurrió. Apoya fácilmente las celdas de la cuadrícula. Así que lo busqué en Google y encontré algunos tutoriales muy útiles:
Tutorial de diseño personalizado de UICollectionView de Bryan Hansen
Mark Pospesel''s Cómo agregar una vista de decoración a una UICollectionView
LXReorderableCollectionViewFlowLayout
Y aquí está el resultado: (Ignore el problema de inconsistencia de color porque los gráficos que elegí todavía no son perfectos).
Lo que hice:
- Creó un diseño personalizado al crear una clase heredada de LXReorderableCollectionViewFlowLayout (para reordenar) que heredó de UICollectionFlowLayout
- Se agregó una vista de decoración para mostrar el logotipo.
- Añadida una vista de decoración para mostrar las estanterías.
Pero me encontré con algunos problemas:
1. No puedo desplazarme en absoluto si los elementos se pueden mostrar en una pantalla
Luego agregué el siguiente código, para agrandar el tamaño del contenido.
- (CGSize)collectionViewContentSize
{
return CGSizeMake(self.collectionView.bounds.size.width, self.collectionView.bounds.size.height+100);
}
Entonces puedo desplazarme ahora. Aquí tiré hacia abajo la primera fila:
Se puede ver que la vista de decoración del logotipo está funcionando.
2. Pero tengo la segunda serie de problemas cuando levanto la última fila:
Puede ver que la vista de decoración no se agrega en la parte del cuadro verde.
3. El fondo de la vista de decoración de la estantería se está oscureciendo cada vez más. (Por favor refiérase al mismo problema aquí
4. La barra del estante de libros a veces se mueve cuando reordeno los artículos
Enumero algunos de los códigos importantes aquí:
- (void)prepareLayout
{
// call super so flow layout can do all the math for cells, headers, and footers
[super prepareLayout];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *shelfLayoutInfo = [NSMutableDictionary dictionary];
// decoration view - emblem
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
UICollectionViewLayoutAttributes *emblemAttributes =
[UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[EmblemView kind]
withIndexPath:indexPath];
emblemAttributes.frame = [self frameForEmblem:YES];
dictionary[[EmblemView kind]] = @{indexPath: emblemAttributes};
// Calculate where shelves go in a vertical layout
int sectionCount = [self.collectionView numberOfSections];
CGFloat y = 0;
CGFloat availableWidth = self.collectionViewContentSize.width - (self.sectionInset.left + self.sectionInset.right);
int itemsAcross = floorf((availableWidth + self.minimumInteritemSpacing) / (self.itemSize.width + self.minimumInteritemSpacing));
for (int section = 0; section < sectionCount; section++)
{
y += self.headerReferenceSize.height;
//y += self.sectionInset.top;
int itemCount = [self.collectionView numberOfItemsInSection:section];
int rows = ceilf(itemCount/(float)itemsAcross)+1; // add 2 more empty row which doesn''t have any data
for (int row = 0; row < rows; row++)
{
indexPath = [NSIndexPath indexPathForItem:row inSection:section];
shelfLayoutInfo[indexPath] = [NSValue valueWithCGRect:CGRectMake(0,y, self.collectionViewContentSize.width, self.itemSize.height + DECORATION_HEIGHT)];
y += self.itemSize.height;
if (row < rows - 1)
y += self.minimumLineSpacing;
}
y += self.sectionInset.bottom;
y += self.footerReferenceSize.height;
}
dictionary[[ShelfView kind]] = shelfLayoutInfo;
self.shelfLayoutInfo = dictionary;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *attributesArrayInRect = [super layoutAttributesForElementsInRect:rect];
// cell layout info
for (BookShelfLayoutAttributes *attribs in attributesArrayInRect)
{
attribs.zIndex = 1;
CATransform3D t = CATransform3DIdentity;
t = CATransform3DTranslate(t, 0, 0, 40);
attribs.transform3D = CATransform3DRotate(t, 15 * M_PI / 180, 1, 0, 0);
}
// Add our decoration views (shelves)
NSMutableDictionary* shelfDictionary = self.shelfLayoutInfo[[ShelfView kind]];
NSMutableArray *newArray = [attributesArrayInRect mutableCopy];
[shelfDictionary enumerateKeysAndObjectsUsingBlock:^(id key, NSValue* obj, BOOL *stop) {
if (CGRectIntersectsRect([obj CGRectValue], rect))
{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[ShelfView kind] withIndexPath:key];
attributes.frame = [obj CGRectValue];
NSLog(@"decorationView rect = %@",NSStringFromCGRect(attributes.frame));
attributes.zIndex = 0;
//attributes.alpha = 0.5; // screenshots
[newArray addObject:attributes];
}
}];
attributesArrayInRect = [NSArray arrayWithArray:newArray];
NSMutableDictionary* emblemDictionary = self.shelfLayoutInfo[[EmblemView kind]];
NSMutableArray *newArray2 = [attributesArrayInRect mutableCopy];
[emblemDictionary enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *innerStop) {
if (CGRectIntersectsRect(rect, attributes.frame)) {
[newArray2 addObject:attributes];
}
}];
attributesArrayInRect = [NSArray arrayWithArray:newArray2];
return attributesArrayInRect;
}
Apreciaré si eres lo suficientemente paciente como para leer esta publicación y proporcionar algún consejo o sugerencia. Y publicaré el código fuente completo si puedo solucionar todos los problemas. Gracias de antemano.
Yo sugeriría revisar su última fila y hacer la [self.collectionView ScrollEnable: NO] igual para la primera fila, establecer el color de fondo claro de collectionView y collectionViewCell y los conjuntos de imágenes de esa estantería en la vista de fondo.