2014年5月1日木曜日

【iOS】UICollectionViewCellの中のImageが任意のセルとズレる問題について

UICollectionViewCellにUIImageViewをのせて使うとき、後から各セルの画像を更新して他の画像と入れ替えたいときがあります。
自分の場合、CoreDataから返ってくる値に応じて画像を入れ替えたかったのですが、
たとえば、cellの中身を変えたいとしたときはUICollectionVIewのデリゲートメソッドのcellForItemAtIndexPath:の中をいじります。



- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"Cell";
    
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
    
    UIImageView *imageView = [[UIImageView alloc] init];
    imageView.frame = CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height);
    
    //CoreDataからとってきた値に応じて、imageViewにのせる画像を変更する
    //ちなみにCoreData周りはMagicalRecordを使ってました
    CoreDataManager *coreData = [CoreDataManager MR_findFirstWithPredicate:[NSPredicateWithFormat:@"date == %@", indexPath.row]];
    
    if (coreData.index == [NSNumber numberWithInt:0]) {
        imageView.image = [UIImage imageNamed:@"hoge0.png"];
    }else if (coreData.index == [NSNumber numberWithInt:1]){
        imageView.image = [UIImage imageNamed:@"hoge1.png"];
    }else if (coreData.index == [NSNumber numberWithInt:2]){
        imageView.image = [UIImage imageNamed:@"hoge2.png"];
    }
    else{
        imageView.image = [UIImage imageNamed:@"hoge3.png"];
    }
    
    [cell.contentView addSubview:imageView];
    
    return cell;
}



こんなかんじだったりします。


あとでどこか任意のタイミングでこの画像を別の画像に変えたいという時、UICollectionViewのreloadDataメソッドで データをリロードしてやれば万事OKだと思っていたのですが、
indexPath.row == 1;のセルの画像を差し替えてるはずなのに、
indexPath.row == 3;のほうに画像が入るということが起きました。

なんでかとずっと悩んでいたら助言をいただき、 UICollectionViewCellのprepareForReuseというメソッドの中でimageView.image == nil;にしていなかったのが原因でした。

最終的にはUICollectionViewCellを拡張して、UIImageViewもその中でプロパティとして設定してやって、拡張したクラスの中でprepareForReuseも書いてやりました。



- (void)prepareForReuse
{
    [super prepareForReuse];
    
    _imageView.image = nil;
}



参考にさせていただいたところ https://github.com/magickworx/SimplePhotoDownloader

0 件のコメント:

コメントを投稿