J'ai une UICollectionView avec trois cellules prototypes différentes, chacune avec des hauteurs différentes définies via Storyboard. Au cours de l'exécution, la vue Collection utilise sa propre taille de cellule, en ignorant celles de Storyboard.
J'utilise actuellement collectionView: layout: sizeForItemAtIndexPath: avec quelques conditions pour définir chaque CGSize directement.
Y a-t-il une meilleure façon de définir les tailles de cellules? Je ne semble pas être en mesure de récupérer la taille de Storyboard de chaque cellule, et CGSizeMake semble trop codé en dur et pas vraiment flexible.
Il semble qu'il n'y a actuellement aucun moyen facile de:
sizeForItemAtIndexPath
). Une méthode proposée ici (pour UITableViews) ne fonctionne pas, car l'utilisation de dequeueReusableCellWithReuseIdentifier
dans sizeForItemAtIndexPath
provoquera une boucle indéfinie.
Cependant, j'ai réussi à le faire de la manière suivante :
Ajoutez un identifiant de réutilisation unique (sur tous les storyboards UICollectionViewCell
dans chaque storyboard) dans chacune de vos cellules prototypes UICollectionView
de tous les Storyboards.
Ajoutez une phase de UICollectionViewCell
Run script
à votre projet avec le script qui extrait les tailles d'image UICollectionViewCell
de tous les Storyboards.
output=${PROJECT_DIR}/StoryboardPrototypeCellSizes.h printf "@{" > $output for storyboard in $(find ${PROJECT_DIR} -name "*.storyboard") do echo "Scanning storyboard $storyboard..." delimiter= for line in $(xpath $storyboard "//collectionViewCell/@reuseIdentifier[ssortingng-length()>0] | //collectionViewCell/rect" 2>&-) do case $line in reuseIdentifier*) reuseIdentifier=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line) ;; width*) if [ -n "$reuseIdentifier" ]; then width=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line) fi ;; height*) if [ -n "$reuseIdentifier" ]; then height=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line) fi ;; esac if [ -n "$reuseIdentifier" ] && [ -n "$width" ] && [ -n "$height" ]; then printf "$delimiter@\"$reuseIdentifier\" : [NSValue valueWithCGSize:CGSizeMake($width, $height)]" >> $output unset reuseIdentifier unset width unset height delimiter=,\\n fi done done printf "};\n" >> $output
Cela crée un file d'en-tête appelé StoryboardPrototypeCellSizes.h
avec un exemple de contenu suivant:
@{@"TodayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 80)], @"SpecialDayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 42)], @"NameDayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 30)]};
Ajoutez une méthode d'assistance pour renvoyer l'identificateur de réutilisation UICollectionViewCell
dans le controller de vue contrôlant votre UICollectionView
:
- (NSSsortingng *)cellReuseIdentifierAtIndexPath:(NSIndexPath *)indexPath { switch (indexPath.item) { case 0: return @"TodayCell"; case 1: return @"SpecialDayCell"; case 2: return @"NameDayCell"; } return nil; }
Veillez à utiliser le même identificateur de réutilisation dans cellForItemAtIndexPath
:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: [self cellReuseIdentifierAtIndexPath:indexPath] forIndexPath:indexPath]; ...
Enfin, implémentez sizeForItemAtIndexPath
:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *storyboardPrototypeCellSizes = #import "StoryboardPrototypeCellSizes.h" return [(NSValue *)storyboardPrototypeCellSizes[ [self cellReuseIdentifierAtIndexPath:indexPath] ] CGSizeValue]; }
Cette solution vous permet de définir une seule fois les tailles de cellules du prototype UICollectionViewCell
dans le (s) Storyboard (s) et de ne pas UICollectionViewCell
non-App Store à l'exécution.
**** Edit: **** Vous pouvez également récupérer les tailles UICollectionReusableView en ajoutant un autre script avec le même contenu et en remplaçant "collectionViewCell" par "collectionReusableView", et en renommant le file d'en-tête, par exemple, StoryboardReusableViewSizes.h
Il n'y a pas de meilleure façon de définir la taille des cellules. Les tailles de cellules sont utilisées à plusieurs endroits dans UICollectionView – pour le positionnement, pour l'indicateur de défilement. Et il est très important de les recevoir aussi vite que possible au cas où l'user ferait défiler la collection avec des milliers de petites cellules par exemple. Donc, créez une cellule et requestz-en au sujet de sa taille n'est pas une option. Vous devez implémenter collectionView: layout: sizeForItemAtIndexPath: et cela devrait fonctionner rapidement.
Utilisez-vous la disposition de stream dans votre UICollectionView
? Si oui, vous pouvez utiliser la méthode UICollectionViewDelegateFlowLayout
protocole UICollectionViewDelegateFlowLayout
pour fournir la taille d'une cellule. Si vous ne rencontrez pas de problèmes lors de l'utilisation des composants OSS dans votre application, RFQuiltLayout peut être utilisé pour cela.