【问题标题】:UICollectionView does not produce cellsUICollectionView 不生成单元格
【发布时间】:2014-07-14 16:04:48
【问题描述】:

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

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

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

问题:它不起作用,集合视图存在但单元格不存在。我在我的代码和第二个 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 和其他类似的东西,但我想自己编写并理解它。任何帮助将不胜感激!

【问题讨论】:

  • 欢迎来到 SO。您能否缩小您的问题范围。您在这里有很多代码,但您没有确定错误发生的位置(如堆栈跟踪等)。请帮助我们帮助您。 :)
  • @kgdesouz 没有错误。这可行,但不应该这样做。基本上,这段代码很简单,可以工作,但有另一种布局。所有关于单元格的东西都是从 tut 带来的。据我所知,单元格和布局是独立的,彼此一无所知。那么为什么它不初始化单元格呢?这就是问题所在。为了更清楚,您可以从这里下载 tut:damir.me/implementing-uicollectionview-layout
  • 你有没有想过解决方案?

标签: ios objective-c xcode uicollectionview uicollectionviewcell


【解决方案1】:

我看到一个不匹配的重用标识符。

你正在注册这个:

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

然后尝试出队:

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

cellID 需要与cellIdentifier 相同。

【讨论】:

  • 是的,我的错,谢谢。因为它没有初始化单元格,所以问题被打开了。
猜你喜欢
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多