iOS:如何在UICollectionView上实现不同区域的背景颜色分离?

4
我有一个UICollectionView,背景色为灰色,但我想让其中一个部分的背景色为白色。我发现这并不像我希望的那样简单(即该部分具有我可以设置的属性)。
从查看如何更改UICollectionView中整个部分的背景颜色? 可以得知,建议使用装饰视图,并且此问题UICollectionView Decoration View通过子类化UICollectionReusableViewUICollectionViewFlowLayout帮助我更改了部分颜色。
我的问题是,我无法获取部分高度(动态的),以设置UIView高度,而且我的下一个部分的开头为空,直到对其进行reloadData调用。
以下是我的代码: WhiteBackgroundCollectionReusableView Class:
#import <UIKit/UIKit.h>

@interface WhiteBackgroundCollectionReusableView : UICollectionReusableView

@end

@implementation WhiteBackgroundCollectionReusableView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [self setBackgroundColor:[UIColor redColor]];
    }
    return self;
}

@end

WhiteBackgroundCollectionViewFlowLayout类

#import <UIKit/UIKit.h>

#import "WhiteBackgroundCollectionReusableView.h"

@interface WhiteBackgroundCollectionViewFlowLayout : UICollectionViewFlowLayout

@end

@implementation WhiteBackgroundCollectionViewFlowLayout

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code

        [self registerClass:[WhiteBackgroundCollectionReusableView class] forDecorationViewOfKind:@"WhiteSection"];
    }
    return self;
}

- (UICollectionViewLayoutAttributes*)layoutAttributesForDecorationViewOfKind:(NSString*)decorationViewKind atIndexPath:(NSIndexPath*)indexPath
{
    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];

    if(indexPath.section == 0) {
        layoutAttributes.frame = CGRectMake(0.0, 0.0, self.collectionViewContentSize.width, 100);

        layoutAttributes.zIndex = -1;
    }

    return layoutAttributes;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *allAttributes = [[NSMutableArray alloc] initWithCapacity:4];

    [allAttributes addObject:[self layoutAttributesForDecorationViewOfKind:@"WhiteSection" atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]];

    for(NSInteger i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
        [allAttributes addObject:layoutAttributes];
    }

    return allAttributes;
}

@end

然后我在viewDidLoad方法中将我的流式布局分配给我的UICollectionViewController中的UICollectionView:

[_collectionView setCollectionViewLayout:[[WhiteBackgroundCollectionViewFlowLayout alloc] init]];

请问我可以从这里去哪里??

更新: 我已经解决了下一部分未显示的问题。为此,我需要将zIndex更改为1,因此我的layoutAttributesForElementsInRect函数现在如下所示:

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

    for(UICollectionViewLayoutAttributes *attributes in array) {
        attributes.zIndex = 1;
    }

    NSMutableArray *newArray = [array mutableCopy];

    [newArray addObject:[self layoutAttributesForDecorationViewOfKind:@"WhiteSection" atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]];

    for(NSInteger i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
        [newArray addObject:layoutAttributes];
    }

    array = [NSArray arrayWithArray:newArray];

    return array;
}

现在我需要的只是一种获取部分高度的方法!请帮忙!:)

2个回答

1

我的解决方案可以在https://github.com/s-atif-jamil/CollectionSectionView上找到。

在SectionBackgroundLayout.h文件中:

@interface SectionBackgroundLayout : UICollectionViewFlowLayout

@property (assign, nonatomic) BOOL alternateBackgrounds;
@property (strong, nonatomic) NSArray *decorationViewOfKinds;

@end

在 SectionBackgroundLayout.m 中

#import "SectionBackgroundLayout.h"

@interface SectionBackgroundLayout ()

@property (strong, nonatomic) NSMutableArray *itemAttributes;

@end

@implementation SectionBackgroundLayout


- (void)prepareLayout
{
    [super prepareLayout];
    self.itemAttributes = [NSMutableArray new];

    NSInteger numberOfSection = self.collectionView.numberOfSections;
    for (int section=0; section<numberOfSection; section++)
    {
        if (!self.alternateBackgrounds && section == self.decorationViewOfKinds.count)
            break;

        NSString *decorationViewOfKind = self.decorationViewOfKinds[section % self.decorationViewOfKinds.count];
        if ([decorationViewOfKind isKindOfClass:[NSNull class]])
            continue;

        NSInteger lastIndex = [self.collectionView numberOfItemsInSection:section] - 1;
        if (lastIndex < 0)
            continue;

        UICollectionViewLayoutAttributes *firstItem = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
        UICollectionViewLayoutAttributes *lastItem = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:lastIndex inSection:section]];

        CGRect frame = CGRectUnion(firstItem.frame, lastItem.frame);
        frame.origin.x -= self.sectionInset.left;
        frame.origin.y -= self.sectionInset.top;

        if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal)
        {
            frame.size.width += self.sectionInset.left + self.sectionInset.right;
            frame.size.height = self.collectionView.frame.size.height;
        }
        else
        {
            frame.size.width = self.collectionView.frame.size.width;
            frame.size.height += self.sectionInset.top + self.sectionInset.bottom;
        }


        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewOfKind withIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
        attributes.zIndex = -1;
        attributes.frame = frame;
        [self.itemAttributes addObject:attributes];
        [self registerNib:[UINib nibWithNibName:decorationViewOfKind bundle:[NSBundle mainBundle]] forDecorationViewOfKind:decorationViewOfKind];
    }
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributes = [NSMutableArray arrayWithArray:[super layoutAttributesForElementsInRect:rect]];
    for (UICollectionViewLayoutAttributes *attribute in self.itemAttributes)
    {
        if (!CGRectIntersectsRect(rect, attribute.frame))
            continue;

        [attributes addObject:attribute];
    }

    return attributes;
}

@end

在视图控制器中
- (void)viewDidLoad
{
    [super viewDidLoad];
    SectionBackgroundLayout *layout = (id)self.collectionView.collectionViewLayout;
    layout.decorationViewOfKinds = @[@"SectionBackgroundView1", @"SectionBackgroundView2", [NSNull null]];
    ...
}

谢谢。这节省了我很多时间。 - Muhammad Zeeshan

0
我正在使用这种方法来计算部分大小。
-(CGRect) rectForSectionAtIndextPath:(NSIndexPath *) indexPath
{
  NSInteger count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section];

UICollectionViewLayoutAttributes *first = [self.collectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexPath.section]];
CGFloat startY = first.frame.origin.y;

UICollectionViewLayoutAttributes *last = [self.collectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:(count-1) inSection:indexPath.section]];
CGFloat endY = last.frame.origin.y + last.frame.size.height;

return CGRectMake(0, startY, self.collectionViewContentSize.width, endY-startY);

 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接