Modifier la taille de UICollectionViewCell sur différentes orientations de périphérique

J'utilise un UICollectionView avec UICollectionViewFlowLayout .

Je définis la taille de chaque cellule à travers le

 collectionView:layout:sizeForItemAtIndexPath: 

Lorsque je passe du mode portrait au mode paysage, je souhaite ajuster la taille de chaque cellule pour l'adapter complètement à la taille de la collection, sans laisser d'espace entre les cellules.

Des questions:

1) Comment changer la taille d'une cellule après un événement de rotation?

2) Et, encore mieux, comment faire la layout où les cellules correspondent toujours à la taille de l'écran?

1) Vous pouvez maintenir et échanger plusieurs objects de layout, mais il existe un moyen plus simple. Ajoutez simplement ce qui suit à votre sous-class UICollectionViewController et ajustez les tailles selon vos besoins:

 - (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]; } 

Appeler -performBatchUpdates:completion: invalidera la layout et resizea les cellules avec animation (vous pouvez simplement passer nil aux deux params de bloc si vous n'avez pas d'ajustements supplémentaires à effectuer).

2) Au lieu de coder en dur les tailles d'éléments dans -collectionView:layout:sizeForItemAtIndexPath , il suffit de split la hauteur ou la largeur des limites de collectionView par le nombre de cellules que vous voulez ajuster à l'écran. Utilisez la hauteur si votre collection défile horizontalement ou la largeur si elle défile verticalement.

Si vous ne voulez pas d'animations supplémentaires apscopes par performBatchUpdates:completion: utilisez simplement invalidateLayout pour forcer le recouvrement de collectionViewLayout.

 - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self.collectionView.collectionViewLayout invalidateLayout]; } 

J'ai résolu en utilisant deux UICollectionViewFlowLayout. Un pour le portrait et un pour le paysage. Je les assigne à ma collectionVoir dinamiquement dans -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]; } 

Ensuite, j'ai simplement modifié mes methods de collectionViewFlowLayoutDelgate comme ceci

 - (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; } 

Enfin je passe d'une layout à une autre en rotation

 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) { [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout animated:YES]; } else { [self.menuCollectionView setCollectionViewLayout:self.portraitLayout animated:YES]; } } 

Il existe un moyen simple de définir la taille de la cellule de la vue de collection:

 UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout; layout.itemSize = CGSizeMake(cellSize, cellSize); 

Je ne sais pas si c'est animé.

Swift: Collection Afficher la cellule dont n% de la hauteur de l'écran

J'avais besoin d'une cellule qui avait un certain pourcentage de hauteur de vue, et resize avec la rotation de l'appareil.

Avec l'aide d'en haut, voici la solution

 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) } 

Si vous utilisez la invalidate layout en invalidate layout autolayout Vous autolayout juste besoin d' invalidate layout dans votre controller de vue lors de la rotation et d'ajuster le offset dans votre sous-class de disposition de stream.

Donc, dans votre vue controller –

 override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { self.galleryCollectionView.collectionViewLayout.invalidateLayout() } 

Et dans votre 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); } } }