Comment ajouter des vues entre UICollectionViewCells dans UICollectionView?

j'essaie d'ajouter UIViews entre mon UICollectionViewCells dans mon UICollectionView et je ne sais pas comment je pourrais le faire. Je suis en train d'accomplir quelque chose comme ceci:

Screenshot

je vais probablement avoir besoin d'écrire une coutume UICollectionViewLayout, mais je ne sais pas vraiment par où commencer.

24
demandé sur Marco Pompei 2013-04-01 23:03:21
la source

5 ответов

j'ai étudié plus de la façon dont UICollectionViewLayouts de travail et compris comment le résoudre. J'ai un UICollectionReusableView sous-classe appelée OrangeView qui sera placé entre mes vues, que j'ai écrit un UICollectionViewFlowLayout sous-classe appelée CategoriesLayout cela traitera de ma mise en page.

Désolé pour le gros bloc de code, mais voici à quoi ça ressemble:

@implementation CategoriesLayout

- (void)prepareLayout {
    // Registers my decoration views.
    [self registerClass:[OrangeView class] forDecorationViewOfKind:@"Vertical"];
    [self registerClass:[OrangeView class] forDecorationViewOfKind:@"Horizontal"];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath {
    // Prepare some variables.
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:indexPath.row+1 inSection:indexPath.section];

    UICollectionViewLayoutAttributes *cellAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
    UICollectionViewLayoutAttributes *nextCellAttributes = [self layoutAttributesForItemAtIndexPath:nextIndexPath];

    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];

    CGRect baseFrame = cellAttributes.frame;
    CGRect nextFrame = nextCellAttributes.frame;

    CGFloat strokeWidth = 4;
    CGFloat spaceToNextItem = 0;
    if (nextFrame.origin.y == baseFrame.origin.y)
        spaceToNextItem = (nextFrame.origin.x - baseFrame.origin.x - baseFrame.size.width);

    if ([decorationViewKind isEqualToString:@"Vertical"]) {
        CGFloat padding = 10;

        // Positions the vertical line for this item.
        CGFloat x = baseFrame.origin.x + baseFrame.size.width + (spaceToNextItem - strokeWidth)/2;
        layoutAttributes.frame = CGRectMake(x,
                                            baseFrame.origin.y + padding,
                                            strokeWidth,
                                            baseFrame.size.height - padding*2);
    } else {
        // Positions the horizontal line for this item.
        layoutAttributes.frame = CGRectMake(baseFrame.origin.x,
                                            baseFrame.origin.y + baseFrame.size.height,
                                            baseFrame.size.width + spaceToNextItem,
                                            strokeWidth);
    }

    layoutAttributes.zIndex = -1;
    return layoutAttributes;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *baseLayoutAttributes = [super layoutAttributesForElementsInRect:rect];
    NSMutableArray * layoutAttributes = [baseLayoutAttributes mutableCopy];

    for (UICollectionViewLayoutAttributes *thisLayoutItem in baseLayoutAttributes) {
        if (thisLayoutItem.representedElementCategory == UICollectionElementCategoryCell) {
            // Adds vertical lines when the item isn't the last in a section or in line.
            if (!([self indexPathLastInSection:thisLayoutItem.indexPath] ||
                  [self indexPathLastInLine:thisLayoutItem.indexPath])) {
                UICollectionViewLayoutAttributes *newLayoutItem = [self layoutAttributesForDecorationViewOfKind:@"Vertical" atIndexPath:thisLayoutItem.indexPath];
                [layoutAttributes addObject:newLayoutItem];
            }

            // Adds horizontal lines when the item isn't in the last line.
            if (![self indexPathInLastLine:thisLayoutItem.indexPath]) {
                UICollectionViewLayoutAttributes *newHorizontalLayoutItem = [self layoutAttributesForDecorationViewOfKind:@"Horizontal" atIndexPath:thisLayoutItem.indexPath];
                [layoutAttributes addObject:newHorizontalLayoutItem];
            }
        }
    }

    return layoutAttributes;
}

@end

j'ai aussi écrit une catégorie à certaines méthodes pour vérifier si un chemin d'index est le dernier en ligne, dans la dernière ligne ou le dernier d'une section:

@implementation UICollectionViewFlowLayout (Helpers)

- (BOOL)indexPathLastInSection:(NSIndexPath *)indexPath {
    NSInteger lastItem = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section] -1;
    return  lastItem == indexPath.row;
}

- (BOOL)indexPathInLastLine:(NSIndexPath *)indexPath {
    NSInteger lastItemRow = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section] -1;
    NSIndexPath *lastItem = [NSIndexPath indexPathForItem:lastItemRow inSection:indexPath.section];
    UICollectionViewLayoutAttributes *lastItemAttributes = [self layoutAttributesForItemAtIndexPath:lastItem];
    UICollectionViewLayoutAttributes *thisItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];

    return lastItemAttributes.frame.origin.y == thisItemAttributes.frame.origin.y;
}

- (BOOL)indexPathLastInLine:(NSIndexPath *)indexPath {
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:indexPath.row+1 inSection:indexPath.section];

    UICollectionViewLayoutAttributes *cellAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
    UICollectionViewLayoutAttributes *nextCellAttributes = [self layoutAttributesForItemAtIndexPath:nextIndexPath];

    return !(cellAttributes.frame.origin.y == nextCellAttributes.frame.origin.y);
}

@end

Et voici le résultat final:

Final Result

46
répondu Marco Pompei 2013-04-03 23:39:01
la source

si vous utilisez des sections et que la mise en page est appropriée, vous pouvez utiliser des en-têtes de section et des pieds de page.

mais d'après votre illustration, il semble que vous ayez juste besoin de définir UICollectionViewCell pour contenir ces vues. Ainsi, lorsque vous vous inscrivez votre classe:

[collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];

mettez ces images de bordure dans la sous-classe de la cellule UICollectionView (dans le cas ci-dessus, "CollectionViewCell"). Cela semble être l'approche la plus facile.

En voici un I utilisation:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.restorationIdentifier = @"Cell";
        self.backgroundColor = [UIColor clearColor];
        self.autoresizingMask = UIViewAutoresizingNone;
        const CGFloat borderWidth = 3.0f;
        UIView *bgView = [[UIView alloc] initWithFrame:frame];
        bgView.layer.borderColor = [UIColor blackColor].CGColor;
        bgView.layer.borderWidth = borderWidth;
        bgView.layer.cornerRadius = 6.0f;
        self.selectedBackgroundView = bgView;
    }
    return self;
}
0
répondu RegularExpression 2013-04-01 23:18:30
la source

on dirait que si votre fond collectionView était vert et contentView blanc vous pourriez obtenir les horizontales avec un espace entre les cellules minimumLineSpacing. L'écart vertical serait la partie délicate, mais si vous étiez créatif avec votre contentView et mettre le minimumInteritemSpacing vous pourriez l'obtenir avec soin.

0
répondu Samuel 2013-04-03 06:47:18
la source

tout d'abord, vous devez définir edge insets pour les cellules de collecte, après que vous devez définir frame pour la vue séparateur programmatically

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING);
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y+cell.frame.size.height, cell.frame.size.width, 2)];
    seperatorView.backgroundColor = [UIColor grayColor];
    [collectionView addSubview:seperatorView];
    [collectionView bringSubviewToFront:seperatorView];
}
-1
répondu Gavidi Harikrishna 2014-12-22 16:54:21
la source

Wow. C'est beaucoup de code dans les autres réponses juste pour une ligne de séparation entre les lignes..

C'est comment je l'ai résolu. D'abord, vous aurez besoin d'ajouter le séparateur de ligne à l'intérieur de la cellule. Assurez-vous que vous continuez à le faire glisser en le faisant plus large que la largeur réelle de la cellule afin que si votre largeur de la cellule est de 60p votre ligne de séparateur sera de 70.

@implementation CollectionViewController
{
    NSArray *test;
    int currentLocInRow;
}

à l'intérieur cellForItemAtIndexPath:

if((indexPath.row+1) % 4 == 0)
    {
        cell.clipsToBounds = YES;
    }
    else
    {
        cell.clipsToBounds = NO;
    }
    currentLocInRow++;

    if([test count] - indexPath.row+1 < 4 - currentLocInRow)
    {
        cell.lineSeparator.alpha = 0;
    }
    else
    {
        cell.lineSeparator.alpha = 1;
    }
    if(currentLocInRow==4)currentLocInRow=0;

enter image description here

Si vous voulez une séparation à la fin de la collecte vue mais il y a une chance que vous n'obtiendrez pas 4 cellules à la dernière rangée, vous pouvez ajouter une vue simple Collection réutilisable comme pied de page.

-1
répondu Segev 2015-08-07 11:08:10
la source