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