UICollectionView不生成单元格

时间:2014-07-14 16:04:48

标签: ios objective-c xcode uicollectionview uicollectionviewcell

我想创建一个带有自定义布局的集合视图,它允许单元格跨越多行,如下所示:

http://stripysock.com.au/blog/2013/2/21/creating-a-custom-collection-view-layout

作者还为我们提供了定位单元格和计算内容大小的方法 我找到了另一个啧啧http://damir.me/implementing-uicollectionview-layout 使用源代码,它几乎是我需要的。问题是在这个项目中,单元格只跨越列,因此单元格的高度是固定的,因此逻辑更简单,每行有独立的列。我没有看到任何方式如何改变第二个tut以满足我的需求并决定合成它们。我借用了第二个tut和第二个自定义布局的单元格,集合视图控制器和app委托的实现。

问题:它没有用,集合视图在那里但是单元格没有。我在我的代码和第二个tut中放了一堆NSLog,并发现我的代码不会调用集合视图单元格的initWithFrame方法,尽管它非常相似。

问题:我在这个问题上挣扎了一个星期,无法理解我所缺少的东西。可以有人提出建议吗?

AppDelegate.m

#import "AppDelegate.h"
#import "CollectionViewController.h"
#import "CollectionViewLayout.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //именно здесь мы создаем наш collection view
    CollectionViewLayout *collectionViewLayout = [[CollectionViewLayout alloc] init];
    NSLog(@"a layout initialized");

    CollectionViewController *collectionViewController = [[CollectionViewController alloc] initWithCollectionViewLayout:collectionViewLayout];
    NSLog(@"a controller is ready");
    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
    [_window setRootViewController:collectionViewController];
    [_window makeKeyAndVisible];
    NSLog(@"end of app delegate");
    return YES;
}

@end

CollectionViewCell.h

#import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell

@property (strong,nonatomic) UILabel *titleLabel;

@end

和CollectionViewCell.m

#import "CollectionViewCell.h"

@implementation CollectionViewCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];NSLog(@"super was initialized");
    if (self)
    {
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0,self.bounds.size.height-50, self.bounds.size.width, 40.0)];
        self.titleLabel.textColor = [UIColor whiteColor];
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        [self.layer setBorderWidth:2];
        [self.layer setBorderColor:[UIColor blackColor].CGColor];
        [self.contentView addSubview:_titleLabel];
        NSLog(@"initializing a cell");
    }
    return self;
}

@end

CollectionViewLayout.h

#import <UIKit/UIKit.h>

@interface CollectionViewLayout : UICollectionViewLayout
@property (strong, nonatomic) NSMutableArray *itemAttributes;
@end

和CollectionViewLayout.m

#import "CollectionViewLayout.h"


@implementation CollectionViewLayout


- (CGSize)collectionViewContentSize
{
    int kNumberOfItemsPerPage = 12;
    int numberOfItems = 24;  

    int numberOfPages = ceil((float)numberOfItems / (float)kNumberOfItemsPerPage);

    // Set the size
    float pageWidth = self.collectionView.frame.size.width;
    float pageHeight = self.collectionView.frame.size.height;
    float totalWidth = numberOfPages*pageWidth;
    CGSize contentSize = CGSizeMake(totalWidth, pageHeight);
    NSLog(@"figuring out content's size");
    return contentSize;
}

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSLog(@"i am there rect attributes ");
    return [_itemAttributes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
        return CGRectIntersectsRect(rect, [evaluatedObject frame]);
    }]];
}

- (void)prepareLayout
{
    //constants
    int kNumberOfItemsPerPage = 12;
    float kColumnWidth = 200;
    float kPadding = 10;
    float kRowHeight = 100;
    float kLargeCellWidth = 410;
    float kLargeCellHeight = 210;
    float kMediumCellHeight = 210;

    NSUInteger numberOfItems = [self.collectionView numberOfItemsInSection:0];

    for (int item=0;item<numberOfItems;item++)
    {
        NSLog(@"preparing layout");
        NSIndexPath *path = [NSIndexPath indexPathForItem:item inSection:0];
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];

        // Figure out what page this item is on
        int pageNumber = floor((float)item / (float)kNumberOfItemsPerPage);

        // Set the horizontal offset for the start of the page
        float pageWidth = self.collectionView.frame.size.width;
        float horizontalOffset = pageNumber * pageWidth;

        // Now, determine which position this cell occupies on the page.
        int indexOnPage = item % kNumberOfItemsPerPage;

        int column = 0;
        switch (indexOnPage) {
            case 0:
            case 3:
            case 5:
                column = 0;
                NSLog(@"!");
                break;
            case 1:
            case 4:
            case 6:
            case 9:
                column = 1;
                NSLog(@"@");
                break;
            case 2:
            case 7:
            case 10:
                column = 2;
                NSLog(@"#");
                break;
            case 8:
            case 11:
                column = 3;
                NSLog(@"$");
                break;
            default:
                column = 0;NSLog(@"j");
                break;
        }
            NSLog(@"preparing layout stage 2");
        int row = 0;
        switch (indexOnPage) {
            case 0:
            case 1:
            case 2:
                row = 0;
                break;
            case 3:
            case 4:
                row = 1;
                break;
            case 5:
            case 6:
            case 7:
            case 8:
                row = 2;
                break;
            case 9:
            case 10:
            case 11:
                row = 3;
                break;
            default:
                row = 0;
                break;
        }

        horizontalOffset = horizontalOffset + ((kColumnWidth + kPadding) * column);
        float verticalOffset = (kRowHeight + kPadding) * row;
            NSLog(@"preparing layout stage 3");
        // finally, determine the size of the cell.
        float width = 10.0;
        float height = 10.0;

        switch (indexOnPage) {
            case 2:
                width = kLargeCellWidth;
                height = kLargeCellHeight;
                NSLog(@"1");
                break;
            case 5:
                width = kColumnWidth;
                height = kMediumCellHeight;
                NSLog(@"3");
                break;
            default:
                width = kColumnWidth;
                height = kRowHeight;
                NSLog(@"2");
                break;
        }

        CGRect frame = CGRectIntegral(CGRectMake(horizontalOffset, verticalOffset, width, height));
        attributes.frame =frame;

        [_itemAttributes addObject:attributes];
            NSLog(@"preparing layout complete");
    }

}

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return NO;
}
@end

最后,控制器的代码在 CollectionViewController.m

#import "CollectionViewController.h"
#import "CollectionViewCell.h"

@interface CollectionViewController ()

@end

@implementation CollectionViewController

- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
{
    self = [super initWithCollectionViewLayout:layout];
    if (self) {
        [self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cellID"];
        self.collectionView.backgroundColor=[UIColor redColor];    }
    NSLog(@"initializing controller with a given layout");
    return self;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSLog(@"returning number of items in section");
    return 24;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CollectionViewCell *cell = (CollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

    cell.titleLabel.text = [NSString stringWithFormat:@"%i", indexPath.row];
    NSLog(@"filling the cell with the text"); 
    return cell;
}

@end

P.S我确实知道RFQuiltLayout,GooglePlusLikeLayout和其他类似的东西,但我想自己编写并理解它。任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:0)

我发现重用标识符不匹配。

您正在注册:

[self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"cellID"];

然后试图将此列出:

CollectionViewCell *cell = (CollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

cellID必须与cellIdentifier相同。