106 votes

Comment aligner au centre les cellules d'un UICollectionView ?

J'utilise actuellement UICollectionView pour la grille de l'interface utilisateur, et cela fonctionne bien. Cependant, j'aimerais que le défilement horizontal soit possible. La grille prend en charge 8 éléments par page et lorsque le nombre total d'éléments est, disons, de 4, voici comment les éléments devraient être disposés lorsque le sens du défilement horizontal est activé :

0 0 x x
0 0 x x

Ici 0 -> élément de collection et x -> Cellules vides

Existe-t-il un moyen de les aligner au centre, par exemple :

x 0 0 x
x 0 0 x

Pour que le contenu soit plus propre ?

L'arrangement ci-dessous pourrait également être une solution que j'attends.

0 0 0 0
x x x x

19voto

bert Points 363

Mettez ceci dans votre délégué de vue de la collection. Elle prend en compte davantage de paramètres de base de la mise en page du flux que les autres réponses et est donc plus générique.

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    NSInteger cellCount = [collectionView.dataSource collectionView:collectionView numberOfItemsInSection:section];
    if( cellCount >0 )
    {
        CGFloat cellWidth = ((UICollectionViewFlowLayout*)collectionViewLayout).itemSize.width+((UICollectionViewFlowLayout*)collectionViewLayout).minimumInteritemSpacing;
        CGFloat totalCellWidth = cellWidth*cellCount + spacing*(cellCount-1);
        CGFloat contentWidth = collectionView.frame.size.width-collectionView.contentInset.left-collectionView.contentInset.right;
        if( totalCellWidth<contentWidth )
        {
            CGFloat padding = (contentWidth - totalCellWidth) / 2.0;
            return UIEdgeInsetsMake(0, padding, 0, padding);
        }
    }
    return UIEdgeInsetsZero;
}

version swift (merci g0ld2k) :

extension CommunityConnectViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {

    // Translated from Objective-C version at: http://stackoverflow.com/a/27656363/309736

        let cellCount = CGFloat(viewModel.getNumOfItemsInSection(0))

        if cellCount > 0 {
            let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
            let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing
            let totalCellWidth = cellWidth*cellCount + spacing*(cellCount-1)
            let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right

            if (totalCellWidth < contentWidth) {
                let padding = (contentWidth - totalCellWidth) / 2.0
                return UIEdgeInsetsMake(0, padding, 0, padding)
            }
        }

        return UIEdgeInsetsZero
    }
}

11voto

Sagar Natekar Points 61

Ma solution pour les cellules de vue de collection de taille statique qui doivent avoir un remplissage à gauche et à droite

func collectionView(collectionView: UICollectionView, 
layout collectionViewLayout: UICollectionViewLayout, 
insetForSectionAtIndex section: Int) -> UIEdgeInsets {

    let flowLayout = (collectionViewLayout as! UICollectionViewFlowLayout)
    let cellSpacing = flowLayout.minimumInteritemSpacing
    let cellWidth = flowLayout.itemSize.width
    let cellCount = CGFloat(collectionView.numberOfItemsInSection(section))

    let collectionViewWidth = collectionView.bounds.size.width

    let totalCellWidth = cellCount * cellWidth
    let totalCellSpacing = cellSpacing * (cellCount - 1)

    let totalCellsWidth = totalCellWidth + totalCellSpacing

    let edgeInsets = (collectionViewWidth - totalCellsWidth) / 2.0

    return edgeInsets > 0 ? UIEdgeInsetsMake(0, edgeInsets, 0, edgeInsets) : UIEdgeInsetsMake(0, cellSpacing, 0, cellSpacing)
}

9voto

Siôn Points 174

J'ai une barre d'étiquettes dans mon application qui utilise une fonction UICollectionView & UICollectionViewFlowLayout avec une rangée de cellules alignées au centre.

Pour obtenir le retrait correct, vous devez soustraire la largeur totale de toutes les cellules (y compris l'espacement) de la largeur de votre fichier de texte. UICollectionView et diviser par deux.

[........Collection View.........]
[..Cell..][..Cell..]
                   [____indent___] / 2

=

[_____][..Cell..][..Cell..][_____]

Le problème est cette fonction -

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

est appelé avant...

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

...donc vous ne pouvez pas itérer sur vos cellules pour déterminer la largeur totale.

Au lieu de cela, vous devez calculer à nouveau la largeur de chaque cellule, dans mon cas j'utilise [NSString sizeWithFont: ... ] car la largeur de mes cellules est déterminée par l'UILabel lui-même.

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    CGFloat rightEdge = 0;
    CGFloat interItemSpacing = [(UICollectionViewFlowLayout*)collectionViewLayout minimumInteritemSpacing];

    for(NSString * tag in _tags)
        rightEdge += [tag sizeWithFont:[UIFont systemFontOfSize:14]].width+interItemSpacing;

    // To center the inter spacing too
    rightEdge -= interSpacing/2;

    // Calculate the inset
    CGFloat inset = collectionView.frame.size.width-rightEdge;

    // Only center align if the inset is greater than 0
    // That means that the total width of the cells is less than the width of the collection view and need to be aligned to the center.
    // Otherwise let them align left with no indent.

    if(inset > 0)
        return UIEdgeInsetsMake(0, inset/2, 0, 0);
    else
        return UIEdgeInsetsMake(0, 0, 0, 0);
}

8voto

Dale Clifford Points 1391

En Swift, le suivant répartira les cellules de manière uniforme en appliquant la bonne quantité de rembourrage sur les côtés de chaque cellule. Bien entendu, vous devez d'abord connaître/régler la largeur de votre cellule.

func collectionView(collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    insetForSectionAtIndex section: Int) -> UIEdgeInsets {

        var cellWidth : CGFloat = 110;

        var numberOfCells = floor(self.view.frame.size.width / cellWidth);
        var edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1);

        return UIEdgeInsetsMake(0, edgeInsets, 60.0, edgeInsets);
}

8voto

Dmitrii Z Points 145

Swift 2.0 Cela fonctionne bien pour moi !

 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2
        return UIEdgeInsetsMake(0, edgeInsets, 0, 0);
    }

Où : Poids de l'écran : en gros, c'est la largeur de ma collection (largeur du plein écran) - j'ai créé des constantes : let screenWight:CGFloat = UIScreen.mainScreen().bounds.width parce que self.view.bounds affiche à chaque fois 600 - à cause des SizeClasses. éléments - réseau de cellules 50 - ma largeur de cellule manuelle 10 - ma distance entre les cellules

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X