在一个视图中显示多个UICollectionView,但显示的项目数是错误的

时间:2013-10-04 02:05:02

标签: iphone ios objective-c uicollectionview

我试图在一个视图中显示多个UICollectionView。该视图是折叠式手风琴风格视图using this custom AccordionView control

目标是显示图像缩略图的多个部分,其中每个部分包含一个UICollectionView,如下所示:

The view's design

下面的数据以NSArray self.wallpaperCollectionArray提供,其中wallpaper_id是缩略图的路径:

(
    {
        name = "Bold Statement";
        "wallpaper_id" = (
            "bs-better",
            "bs-look-forward",
            "bs-now-never",
            "bs-stay-hype",
            "bs-you-awesome"
        );

    },
    {
        name = "Dreamcatcher";
        "wallpaper_id" = (
            "dc-disney",
            "dc-fear",
            "dc-paulo",
            "dc-quit"
        );
    },
    {
        name = "Goods from the good";
        "wallpaper_id" = (
            "gg-get-hurt",
            "gg-jobs",
            "gg-lennon",
            "gg-oprah"
        );
    },
    {
        name = "Random Set";
        "wallpaper_id" = (
            "rs-face",
            "rs-god-knows",
            "rs-good",
            "rs-holtz",
            "rs-positive",
            "rs-read",
            "rs-think"
        );
    },
    {
        name = Traveling;
        "wallpaper_id" = (
            "tr-miller"
        );
    }
)

这是我生成UICollectionView的代码:

- (void)loadView {
    UIView *libraryView = [UIView new];

    CGFloat maxWidth = [[UIScreen mainScreen] bounds].size.width;
    CGFloat maxHeight = [[UIScreen mainScreen] bounds].size.height;

    // Setup accordion
    self.libraryAccordionView = [[AccordionView alloc] initWithFrame:CGRectMake(0, 0, maxWidth, maxHeight)];

    // Re-usable layout for the UICollectionView(s) inside the for loop
    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.itemSize = CGSizeMake(thumbnailSize, thumbnailSize);
    layout.minimumInteritemSpacing = 0;
    layout.minimumLineSpacing = 1;

    // Looping through the array contents:
    int i = 0;
    for(NSDictionary *currentCollectionDictionary in self.wallpaperCollectionArray) {
        NSArray *wallpaperIDs = [currentCollectionDictionary valueForKeyPath:@"wallpaper_id"];
        NSInteger numberOfWallpapers = [wallpaperIDs count];

        // One row contains 4 thumbnails, while each thumbnail's height is 79.
        // So, collectionView height = (total item / 4 + 1) * 79
        NSInteger collectionViewHeight = (numberOfWallpapers / 4 + 1) * thumbnailSize;
        UICollectionView *currentCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, maxWidth, collectionViewHeight)
                                                                     collectionViewLayout:layout];
        [currentCollectionView setDataSource:(id)self];
        [currentCollectionView setDelegate:(id)self];
        NSString *cellIdentifier = [NSString stringWithFormat:@"cell_%d", i];
        [currentCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];

        // Trick to let the delegate and data source functions deal with the multiple UICollectionView's
        [currentCollectionView setTag:i];

        // * --- Create header --- * //
        UIButton *currentHeader = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 30)];
        NSString *currentHeaderTitle = [currentCollectionDictionary valueForKeyPath:@"name"];
        [currentHeader setTitle:currentHeaderTitle forState:UIControlStateNormal];

        [self.libraryAccordionView addHeader:currentHeader withView:currentCollectionView];
        i++;
    }

    [libraryView addSubview:self.libraryAccordionView]
    [self setView:libraryView];
}

数据源方法:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSInteger index = collectionView.tag;
    NSInteger numberOfWallpaper = [[[self.wallpaperCollectionArray objectAtIndex:index] valueForKeyPath:@"wallpaper_id"] count];
    NSLog(@"index is: %d --- # of item is: %d", index, numberOfWallpaper);
    return numberOfWallpaper;
}

// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger index = collectionView.tag;
    NSString *cellIdentifier = [NSString stringWithFormat:@"cell_%d", index];

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
                                                                           forIndexPath:indexPath];

    NSString *thumbnailName = [[[self.wallpaperCollectionArray objectAtIndex:index] valueForKeyPath:@"wallpaper_id"] objectAtIndex:indexPath.row];

    UIImageView *wallpaperImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:thumbnailName]];
    [cell addSubview:wallpaperImage];
    return cell;
}

问题是,所有UICollectionView只显示一个缩略图,虽然看起来他们正在加载正确的缩略图:

the result the result

起初我意识到问题可能出在- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section方法中。

但是,在此测试NSLog(@"index is: %d --- # of item is: %d", index, numberOfWallpaper);中,numberOfWallpaper的结果是正确的:

2013-10-04 08:50:43.992 quo.mk.e[15046:11603] index is: 4 --- # of item is: 1
2013-10-04 08:50:43.993 quo.mk.e[15046:11603] index is: 3 --- # of item is: 7
2013-10-04 08:50:43.994 quo.mk.e[15046:11603] index is: 2 --- # of item is: 4
2013-10-04 08:50:43.994 quo.mk.e[15046:11603] index is: 1 --- # of item is: 4
2013-10-04 08:50:43.995 quo.mk.e[15046:11603] index is: 0 --- # of item is: 5

所以,我正在为numberOfItemsInSection返回正确数量的缩略图。为什么UICollectionView只显示一个缩略图?

1 个答案:

答案 0 :(得分:3)

原来问题在于重复使用布局。使用多个UICollectionView,我们需要创建自己独立的布局。由于某些原因。

- (void)loadView中的循环内移动布局创建可以解决问题:

int i = 0;
for(NSDictionary *currentCollectionDictionary in self.wallpaperCollectionArray) {
    NSArray *wallpaperIDs = [currentCollectionDictionary valueForKeyPath:@"wallpaper_id"];
    NSInteger numberOfWallpapers = [wallpaperIDs count];

    // Layouting
    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.itemSize = CGSizeMake(thumbnailSize, thumbnailSize);
    layout.minimumInteritemSpacing = 0;
    layout.minimumLineSpacing = 1;

    ...