web-dev-qa-db-fra.com

Afficher seulement deux colonnes, avec plusieurs lignes dans un CollectionView à l'aide d'un storyboard

Je souhaite afficher uniquement deux cellules à la suite, quelle que soit la taille de l'écran de l'iPhone. Comme,  End result required

Mon storyboard contient une UICollectionView, liée par des contraintes.

 Storyboard preview

Les paramètres du storyboard pour la UICollectionView sont,  enter image description here

Maintenant, quand je lance ceci dans 6, 5 ou moins, une seule cellule apparaît à la suite. Le code que j'avais utilisé est,

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [categoryImages count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    homePageCells *cell = (homePageCells *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cells" forIndexPath:indexPath];
    cell.categoryName.text = [categoryNames objectAtIndex:indexPath.row];

    return cell;
}

J'ai essayé de détecter la taille de l'écran et d'attribuer par programme la taille de cellule appropriée à l'aide du code,

- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize sizes;


    CGSize result = [[UIScreen mainScreen] bounds].size;
    NSLog(@"%f",result.height);
    if(result.height == 480)
    {
        //Load 3.5 inch xib
        sizes =CGSizeMake(170.f, 170.f);
        NSLog(@"3gs");
    }
    else if(result.height == 568)
    {
        //Load 4 inch xib
        sizes =CGSizeMake(130.f, 130.f);
        NSLog(@"5s");

    }
    else if(result.height == 667.000000)
    {
        //Load 4.7 inch xib
        sizes =CGSizeMake(160.f, 160.f);
        NSLog(@"6");

    }
    else
    {
        NSLog(@"else");

        sizes =CGSizeMake(170.f, 165.f);

    }
    return sizes;
}

Mais je sais aussi que ce n'est pas la bonne façon, alors donnez-moi une bonne façon de gérer cela.

16
rajesh s

Vous pouvez le faire comme ceci: vous n'avez pas besoin de vérifier la taille du périphérique car nous pouvons utiliser la largeur collectionView pour calculer la largeur de la cellule et mettre à jour notre hauteur en conséquence.

Une dernière chose: vous devez utiliser UICollectionViewDelegateFlowLayout & confirmer la méthode de délégation et d'implémentation ci-dessous

  func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

   let padding: CGFloat =  50
   let collectionViewSize = collectionView.frame.size.width - padding

   return CGSizeMake(collectionViewSize/2, collectionViewSize/2)

}

Mise à jour: Swift 4.0

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let padding: CGFloat =  50
        let collectionViewSize = collectionView.frame.size.width - padding

        return CGSize(width: collectionViewSize/2, height: collectionViewSize/2)
    }

Note : J'ai répondu à la question en considérant que les cellules sont de taille carrée

45
Rohit KP

Xcode 8: Swift 3

Je sais que c'est une question plus ancienne, mais j'ai trouvé quelques problèmes avec la réponse acceptée.

Je devais utiliser UICollectionViewDelegateFlowLayout qui n'est pas CollectionViewFlowLayout 

Ensuite

Dans celui-ci, 'Padding' est de type Int et lorsque vous essayez de le soustraire à la variable collectionViewSize, une erreur est renvoyée car ils sont de types différents. Très facile à réparer cependant.

Je viens d'ajouter: CGFloat à la ligne

Enfin, bien qu'il y ait probablement une meilleure façon de le faire, j'ai dû faire correspondre le remplissage en ajustant les contraintes de début et de fin de collectionView.

Donc dans l’ensemble, c’est à quoi ressemblait mon code

extension LandingPageViewController: UICollectionViewDelegateFlowLayout {

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let padding: CGFloat = 25
    let collectionCellSize = collectionView.frame.size.width - padding

  return CGSize(width: collectionCellSize/2, height: collectionCellSize/2)

   }

}
9
RubberDucky4444
- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat padding = 50;
CGFloat cellSize = collectionView.frame.size.width - padding;
return CGSizeMake(cellSize / 2, cellSize / 2);
}
1
sanjeet

J'ai eu des problèmes avec les limites de la collectionView passé dans sizeForItemAtIndexPath n'étant pas correct à ce moment-là.

Un correctif pour cela serait de recharger les cellules dans viewWillAppear pour s'assurer que les limites de collectionView sont correctes.

Une autre consiste à utiliser la classe UIScreen.

-(instancetype)init: {
    self = [super init];
    if (self) {
        width = [[UIScreen mainScreen] bounds].size.width;
    }
    return self;
}

-(CGSize)collectionView:(UICollectionView *)collectionView
                 layout:(UICollectionViewLayout *)collectionViewLayout
 sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    // Two columns with spacing in between
    CGFloat size = ((width / 2) - (kSpacing * 2));
    return CGSizeMake(size, size);

}

Dans ce cas, j'instancie le délégué en tant que classe séparée (d'où init), mais cela peut se faire aussi facilement qu'une extension.

0
Alex Scanlan