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

6voto

user3419059 Points 61

Vous pouvez utiliser https://github.com/keighl/KTCenterFlowLayout comme ça :

KTCenterFlowLayout *layout = [[KTCenterFlowLayout alloc] init];

[self.collectionView setCollectionViewLayout:layout];

2voto

Sandy Chapman Points 831

Je ne sais pas si c'est nouveau dans Xcode 5 ou non, mais vous pouvez maintenant ouvrir l'inspecteur de taille par l'intermédiaire d'Interface Builder et définir une insertion à cet endroit. Cela vous évitera d'avoir à écrire du code personnalisé pour le faire à votre place et devrait augmenter considérablement la vitesse à laquelle vous trouvez les bons décalages.

1voto

Paul Peelen Points 3770

Une autre façon de procéder consiste à définir l'option collectionView.center.x comme ça :

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if let
        collectionView = collectionView,
        layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
    {
        collectionView.center.x = view.center.x + layout.sectionInset.right / 2.0
    }
}

Dans ce cas, en ne respectant que l'encart de droite qui fonctionne pour moi.

1voto

Novamax Points 11

Sur la base de la réponse de l'utilisateur 3676011, je peux proposer une solution plus détaillée avec une petite correction. Cette solution fonctionne très bien sur Swift 2.0 .

enum CollectionViewContentPosition {
    case Left
    case Center
}

var collectionViewContentPosition: CollectionViewContentPosition = .Left

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

    if collectionViewContentPosition == .Left {
        return UIEdgeInsetsZero
    }

    // Center collectionView content

    let itemsCount: CGFloat = CGFloat(collectionView.numberOfItemsInSection(section))
    let collectionViewWidth: CGFloat = collectionView.bounds.width

    let itemWidth: CGFloat = 40.0
    let itemsMargin: CGFloat = 10.0

    let edgeInsets = (collectionViewWidth - (itemsCount * itemWidth) - ((itemsCount-1) * itemsMargin)) / 2

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

Il y avait un problème dans

(CGFloat(elements.count) * 10)))

où devrait se trouver un supplément -1 mentionné.

1voto

Zhong Huiwen Points 529

Voici comment j'ai obtenu une vue de la collection qui était alignée au centre avec un espacement fixe entre les éléments.

#define maxInteritemSpacing 6
#define minLineSpacing 3

@interface MyFlowLayout()<UICollectionViewDelegateFlowLayout>

@end

@implementation MyFlowLayout

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.minimumInteritemSpacing = 3;
        self.minimumLineSpacing = minLineSpacing;
        self.scrollDirection = UICollectionViewScrollDirectionVertical;
    }
    return self;
}

- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *answer = [super layoutAttributesForElementsInRect:rect];

    if (answer.count > 0) {
        NSMutableArray<NSMutableArray<UICollectionViewLayoutAttributes *> *> *rows = [NSMutableArray array];
        CGFloat maxY = -1.0f;
        NSInteger currentRow = 0;

        //add first item to row and set its maxY
        [rows addObject:[@[answer[0]] mutableCopy]];
        maxY = CGRectGetMaxY(((UICollectionViewLayoutAttributes *)answer[0]).frame);

        for(int i = 1; i < [answer count]; ++i) {
            //handle maximum spacing
            UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
            UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
            NSInteger maximumSpacing = maxInteritemSpacing;
            NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);

            if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
                CGRect frame = currentLayoutAttributes.frame;
                frame.origin.x = origin + maximumSpacing;
                currentLayoutAttributes.frame = frame;
            }

            //handle center align
            CGFloat currentY = currentLayoutAttributes.frame.origin.y;
            if (currentY >= maxY) {
                [self shiftRowToCenterForCurrentRow:rows[currentRow]];

                //next row
                [rows addObject:[@[currentLayoutAttributes] mutableCopy]];
                currentRow++;
            }
            else {
                //same row
                [rows[currentRow] addObject:currentLayoutAttributes];
            }

            maxY = MAX(CGRectGetMaxY(currentLayoutAttributes.frame), maxY);
        }

        //mark sure to shift 1 row items
        if (currentRow == 0) {
            [self shiftRowToCenterForCurrentRow:rows[currentRow]];
        }
    }

    return answer;
}

- (void)shiftRowToCenterForCurrentRow:(NSMutableArray<UICollectionViewLayoutAttributes *> *)currentRow
{
    //shift row to center
    CGFloat endingX = CGRectGetMaxX(currentRow.lastObject.frame);
    CGFloat shiftX = (self.collectionViewContentSize.width - endingX) / 2.f;
    for (UICollectionViewLayoutAttributes *attr in currentRow) {
        CGRect shiftedFrame = attr.frame;
        shiftedFrame.origin.x += shiftX;
        attr.frame = shiftedFrame;
    }
}

@end

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