ios - didselectitematindexpath - uicollectionview inside uitableviewcell
Cambiar el tamaƱo de UICollectionViewCell en diferentes orientaciones del dispositivo (6)
Estoy usando un UICollectionView
con UICollectionViewFlowLayout
.
Establecí el tamaño de cada celda a través del
collectionView:layout:sizeForItemAtIndexPath:
Al cambiar de vertical a horizontal, me gustaría ajustar el tamaño de cada celda para que se ajuste por completo al tamaño de CollectionView, sin dejar espacio de relleno entre las celdas.
Preguntas:
1) ¿Cómo cambiar el tamaño de una celda después de un evento de rotación?
2) Y, aún mejor, ¿cómo hacer el diseño donde las celdas siempre se ajustan a todo el tamaño de la pantalla?
1) Puede mantener e intercambiar múltiples objetos de diseño, pero hay una manera más simple. Simplemente agregue lo siguiente a su subclase UICollectionViewController
y ajuste los tamaños según sea necesario:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
// Adjust cell size for orientation
if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
return CGSizeMake(170.f, 170.f);
}
return CGSizeMake(192.f, 192.f);
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self.collectionView performBatchUpdates:nil completion:nil];
}
Llamar a -performBatchUpdates:completion:
invalidará el diseño y cambiará el tamaño de las celdas con la animación (puede pasar el nil a ambos params si no tiene que realizar ajustes adicionales).
2) En lugar de codificar el tamaño de los elementos en -collectionView:layout:sizeForItemAtIndexPath
, solo divida la altura o el ancho de los límites de collectionView por el número de celdas que desea que quepan en la pantalla. Use la altura si su collectionView se desplaza horizontalmente o el ancho si se desplaza verticalmente.
Hay una manera simple de establecer el tamaño de celda de la vista de colección:
UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);
Sin embargo, no estoy seguro si es animable.
Lo resolví usando dos UICollectionViewFlowLayout. Uno para el retrato y otro para el paisaje. Los asigno a mi collectionView dinamically en -viewDidLoad
self.portraitLayout = [[UICollectionViewFlowLayout alloc] init];
self.landscapeLayout = [[UICollectionViewFlowLayout alloc] init];
UIInterfaceOrientation orientationOnLunch = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientationOnLunch)) {
[self.menuCollectionView setCollectionViewLayout:self.portraitLayout];
} else {
[self.menuCollectionView setCollectionViewLayout:self.landscapeLayout];
}
Luego simplemente modifiqué mis métodos collectionViewFlowLayoutDelgate como este
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
CGSize returnSize = CGSizeZero;
if (collectionViewLayout == self.portraitLayout) {
returnSize = CGSizeMake(230.0, 120.0);
} else {
returnSize = CGSizeMake(315.0, 120.0);
}
return returnSize;
}
Última cambio de un diseño a otro en la rotación
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) {
[self.menuCollectionView setCollectionViewLayout:self.landscapeLayout animated:YES];
} else {
[self.menuCollectionView setCollectionViewLayout:self.portraitLayout animated:YES];
}
}
Si está utilizando el autolayout
. Solo necesita invalidate layout
en su controlador de vista al girar y ajustar el offset
en su subclase de diseño de flujo.
Entonces, en su controlador de vista -
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
self.galleryCollectionView.collectionViewLayout.invalidateLayout()
}
Y en tu FlowLayout Subclass
override func prepareLayout() {
if self.collectionView!.indexPathsForVisibleItems().count > 0{
var currentIndex : CGFloat!
currentIndex = CGFloat((self.collectionView!.indexPathsForVisibleItems()[0] as! NSIndexPath).row)
if let currentVal = currentIndex{
self.collectionView!.contentOffset = CGPointMake(currentIndex * self.collectionView!.frame.width, self.collectionView!.contentOffset.y);
}
}
}
Si no desea animaciones adicionales presentadas por performBatchUpdates:completion:
, simplemente use invalidateLayout
para forzar la recarga de collectionViewLayout.
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.collectionView.collectionViewLayout invalidateLayout];
}
Swift: Celda de vista de colección que es n% de la altura de la pantalla
Lo que necesitaba era una celda con un cierto porcentaje de altura de vistas, y cambiaría el tamaño con la rotación del dispositivo.
Con la ayuda de arriba, aquí está la solución
override func viewDidLoad() {
super.viewDidLoad()
automaticallyAdjustsScrollViewInsets = false
// if inside nav controller set to true
}
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
collectionViewLayout.invalidateLayout()
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: 100, height: collectionView.frame.height * 0.9)
}