派生的UICollectionViewCell始终从dequeueReusableCellWithReuseIdentifier返回null

时间:2014-11-24 00:05:22

标签: objective-c xcode ios8 uicollectionview uicollectionviewcell

我以编程方式将UICollectionView添加到控制器,但无论我如何设置它,我都无法在调用dequeueReusableCellWithReuseIdentifier时获得有效的UICollectionViewCell。在显示代码之前,可能会有一些有用的信息:

  • 我使用的是最新的XCode
  • 我在iPad上定位iOS 8.1
  • 我没有使用故事板
  • 我有导航控制器设置,我也使用Core Data

以下是代码:

或者Controller.h

@interface ViewController : UIViewController<UIImagePickerControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

@end

Controller.m或者

@interface ViewController ()

@property (strong, nonatomic) NSMutableArray *images;
@property (strong, nonatomic) UICollectionView *collectionView;

@end

// called by a button in the navigation bar
- (void)addMedia:(id)sender {
    // load test images
    if ([self.images count] == 0) {
        NSBundle *myBundle = [NSBundle mainBundle];
        NSArray *imagesPaths = [myBundle pathsForResourcesOfType:@"png" inDirectory:nil];

        for (NSString *path in imagesPaths) {
            UIImage *newImage = [[UIImage alloc] initWithContentsOfFile:path];

            [self.images addObject:newImage];
        }

        self.introLabel.hidden = YES;

        CGRect rect = CGRectMake(self.view.frame.size.width / 2 - 250,
                                 self.view.frame.size.height / 2 - 250, 500, 500);
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.itemSize = CGSizeMake(120, 120);
        layout.minimumInteritemSpacing = 10;
        self.collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:layout];
        UINib *cellNib = [UINib nibWithNibName:@"ImageViewCell" bundle:nil];
        [self. collectionView registerNib:cellNib forCellWithReuseIdentifier:@"imageCell"];
        //[self.collectionView registerClass:[ImageViewCell class] forCellWithReuseIdentifier:@"imageCell"];
        [self.collectionView setDelegate:self];
        [self.collectionView setDataSource:self];
        [self.view addSubview:self.collectionView];
    }
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.images count];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    // THIS IS ALWAYS NULL
    ImageViewCell *cell = (ImageViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"imageCell" forIndexPath:indexPath];

    cell.image.image = [self.images objectAtIndex:indexPath.row];

    return cell;
}

ImageViewCell.h

@interface ImageViewCell : UICollectionViewCell

@property (strong, nonatomic) IBOutlet UIImageView *image;

@end

ImageViewCell.m

@implementation ImageViewCell

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    // THIS IS ALWAYS NULL!
    return self;
}

@end

在ImageViewCell.xib中,我有一个UICollectionCellView作为主视图,其中包含我尝试填充的UIImageView; UICollectionCellView指向ImageViewCell(派生类)。

我应该提一下,我尝试了一个带有单个控制器的新项目并以编程方式添加UICollectionView并且它可以工作的相同方法,所以我必须丢失一些愚蠢的东西或做一些略有不同的事情,但我不知道它

[编辑]:用解决方案更改了代码。

1 个答案:

答案 0 :(得分:1)

确保在xib文件中File&#39的Owner属性指示实现它的类名。然后,执行:

- (NSString *)reuseIdentifier {
    return @"imageCell";
}

在您的ImageViewCell实现中。也可能有一种方法在界面构建器中设置它,而不是覆盖getter。

顺便说一句,如果你的ImageViewCell是由xib支持的,那么initWithFrame:将不是指定的初始化器,而是initWithCoder。但是你的实现很好,而且你现在不必覆盖initWithCoder。

编辑:正如rdelmar指出的那样,你肯定也应该使用registerNib版本;你不需要以这种方式实现reuseIdentifier getter。