0

我以编程方式向控制器添加了UICollectionView,但无论如何设置,在调用dequeueReusableCellWithReuseIdentifier时无法获得有效的UICollectionViewCell。显示代码,一些信息可能会有所帮助之前:派生的UICollectionViewCell总是从dequeueReusableCellWithReuseIdentifier返回空值

  • 我使用的是最新的XCode
  • 我我不使用故事板
  • iPad上中定位iOS 8.1
  • 我有一个导航控制器设置,我还使用核心数据

下面的代码:

或者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,它的工作原理,所以我必须缺少一些愚蠢或做一些稍微不同的东西,但我不知道它。

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

+0

我不知道这是否是你的问题,但如果你在xib中创建单元格,你应该注册nib而不是类。你的应用崩溃了吗?如果是这样,你会得到什么错误? – rdelmar 2014-11-24 00:49:16

+0

'dequeueReusable ...'只在你注册它的笔尖时自动创建一个单元格。 – 2014-11-24 01:21:16

回答

1

确保在xib文件中File's Owner属性指示实现它的类名。然后,在您的ImageViewCell实现中实现:

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

。也有可能在接口生成器中设置它,而不是重写getter。顺便说一句,如果你的ImageViewCell支持一个xib,initWithFrame:不会是指定的初始化器,而是initWithCoder将会是。但是你的实现没问题,你现在不需要重写initWithCoder。

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

+0

我注册了nib而不是类,并在Interface Builder中添加了标识符。我仍然得到一个空单元'dequeueReusableCellWithReuseIdentifier',但它似乎与UIImageView的连接正在工作,现在我得到了预期的结果。也许在调试器中有些东西是关闭的。 – 2014-11-24 22:14:41

+1

@MarcoCastorina,不要总是相信调试器说什么。方法dequeueReusableCellWithReuseIdentifier:forIndexPath:保证返回一个单元格,如果不能,它会导致该行代码崩溃。所以如果你没有崩溃,那么单元不能为空。 – rdelmar 2014-11-24 23:08:40

+0

需要注意的是:通常情况下,如果我在具有等号的代码行上设置断点/设置变量的值,则很明显,调试器中的细节表示执行之前变量的状态那行代码。 – sammoore 2014-12-21 18:09:38