2016-03-27 4 views
1

を消える: - ユーザープレススタートボタンを - イメージがダウンロードされるだけでなく、テーブルビューでのUITableView - セル内のすべてのデータは、私は次の特性を持っているcustomCellとテーブルビュー、持って

@interface CustomTableViewCell : UITableViewCell 

@property (weak, nonatomic) IBOutlet UIImageView *image; 
@property (weak, nonatomic) IBOutlet UILabel *nameOfImage; 
@property (weak, nonatomic) IBOutlet UIButton *start; 
@property (weak, nonatomic) IBOutlet UIButton *stop; 
@property (weak, nonatomic) IBOutlet UIProgressView *progressView; 
@property (weak, nonatomic) IBOutlet UILabel *realProgressStatus; 

をrealProgressStatusのprogressViewは現在の状況を反映します。この段階ではすべてが完璧に機能しますが、スクロールテーブルビューでセルに戻ると、データで既に満たされています。すべての情報が消えました(nameOfImageを除いて、別に設定しました)。 私はCustomTableViewCellクラスに次のメソッドを実装し:

-(void)prepareForReuse 
{ 
    [super prepareForReuse]; 

    self.progressView.progress = 0.1; 
    self.realProgressStatus.text = @""; 
    self.image.image = [UIImage imageNamed:@"placeholder"]; 
} 

を私はイメージが既にダウンロードセルの数を節約する新しいプロパティNSMutableSet self.tagsOfCellsを実装しました。 私はテーブルビューの方法で変更を加えることを試みたが、効果は同じである:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString* PlaceholderCellIdentifier = @"Cell"; 
    CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier forIndexPath:indexPath]; 
    customCell.delegate = self; 
    customCell.cellIndex = indexPath.row; 
    if (!customCell) 
    { 
     customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
               reuseIdentifier:@"cell"]; 
    } 
    else 
    { 
      NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row]; 

     if (![self.tagsOfCells containsObject:myNum]) 
     { 
      NSLog(@"Row: %ld",(long)indexPath.row); 
      UIImage *img = [UIImage imageNamed:@"placeholder"]; 
      customCell.realProgressStatus.text = @""; 
      customCell.progressView.progress = 0.1; 
      customCell.image.image = img; 
      [customCell setNeedsLayout]; 
     } 
    } 

    if (indexPath.row % 2 == 0) 
     customCell.backgroundColor = [UIColor grayColor]; 
    else 
     customCell.backgroundColor = [UIColor darkGrayColor]; 

    customCell.nameOfImage.text = self.names[indexPath.row]; 
    return customCell; 
} 

はEDIT:

私は画像をダウンロード中のいずれかの方法でself.tagsOfCellsを移入、ここでの方法は次のとおりです。

-(void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    self.customCell.realProgressStatus.text = @"Downloaded"; 

    UIImage *img = [UIImage imageWithData:self.imageData]; 
    self.customCell.image.image = img; 
    self.customCell.tag = self.selectedCell; 
    [self.savedImages setObject:img forKey:self.customCell.nameOfImage.text]; 
    NSNumber *myNum = [NSNumber numberWithInteger:self.selectedCell]; 
    [self.tagsOfCells addObject:myNum]; 

} 

ご協力いただきありがとうございます。

答えて

3

コンテンツに関連するアクションは、prepareForReuse関数では発生しません。

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instm/UITableViewCell/prepareForReuse

のUITableViewCellオブジェクトは再利用可能、つまり、再利用識別子このメソッドは、オブジェクトがのUITableView方法dequeueReusableCellWithIdentifierから戻される直前に呼び出されたされた場合:。パフォーマンス上の理由から、アルファ、編集、選択状態など、コンテンツに関連しないセルの属性のみをリセットする必要があります。 tableView:cellForRowAtIndexPath:のテーブルビューのデリゲートは、セルの再利用時に常にすべてのコンテンツをリセットする必要があります。セルオブジェクトに関連する再利用識別子がない場合、このメソッドは呼び出されません。このメソッドをオーバーライドする場合は、必ずスーパークラスの実装を呼び出す必要があります。

編集

アルフィーは

を次のコード

if (!customCell) 
{ 
    customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:@"cell"]; 
} 
else 
{ 
     NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row]; 

    if (![self.tagsOfCells containsObject:myNum]) 
    { 
     NSLog(@"Row: %ld",(long)indexPath.row); 
     UIImage *img = [UIImage imageNamed:@"placeholder"]; 
     customCell.realProgressStatus.text = @""; 
     customCell.progressView.progress = 0.1; 
     customCell.image.image = img; 
     [customCell setNeedsLayout]; 
    } 
} 

を編集prepareForReuseは私がしようとするだろうcellForRowAtIndexPath

最初のものから戻った後に呼び出されていない、右されています

if (!customCell) 
{ 
    customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:@"cell"]; 
} 

NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row]; 

if (![self.tagsOfCells containsObject:myNum]) 
{ 
    NSLog(@"Row: %ld",(long)indexPath.row); 
    UIImage *img = [UIImage imageNamed:@"placeholder"]; 
    customCell.realProgressStatus.text = @""; 
    customCell.progressView.progress = 0.1; 
    customCell.image.image = img; 
    [customCell setNeedsLayout]; 
} 

これは実際には高価な操作ではなく、このロジックを単一の場所に配置する方がよいでしょう。特にprepareForReuseを取り除いたので、これを変更する必要があります。

スクロールしてからデータを見つけられない場合は、cellForRowAtIndexPathが再度呼び出されているため、追加したばかりの新しいデータがデフォルトデータで上書きされます。

基礎となるデータ構造を持ち、そこでデータを取得したいとします。


私はどうなるのか:

インスタンスについて、あなたは配列

[tableData add:imageData]; 

に行ごとに、このような

NSMutableArray* tableData = [[NSMutableArray alloc] init]; 

追加画像データとして変更可能なリストを維持することができますそれを表示してください。cellForRowAtIndexPath

customCell.image.image = [tableData objectAtIndex:[indexPath row]]; 

これは、データでUITableViewを作成する通常の方法です。こうすることで、たとえスクロールしてもtableDataは同じままになり、結果的に一貫したデータになります。

私はこれを実装していた場合、私はまた、非同期セル内からNSURLSessionを使用して、新しいデータを呼び出します。ちょっとした提案=)

+0

ありがとうございます。私はForReuseメソッドの準備を削除し、cellForRowAtIndexPathで書かれたものだけを使用しますが、データは消えます。条件 - if(![self.tagsOfCells containsObject:myNum])をチェックしても、このセクションには入力されないので、データを上書きしないでください。何らかの理由でそれを行います。私は間違ったことを理解できません.... – Melany

+0

ありがとう)))最終的には動作します!ちなみに、私はあなたのアドバイスが冒険になる可能性があると思います。事前にありがとう))) – Melany

1

私はこれがprepareForReuseの使用とは関係ないと思います。カップルのものは怪物に見えます。

あなたはそれがnilだかどうかを知る前に、あなたがあなたの携帯にdelegatecellIndexプロパティを設定している
  1. 。それがnilの場合、これらのプロパティは決して設定されません。

  2. また、else節は必要ありません。ラップするロジックには、セルをデキューできるかどうかは関係ありません。非ゼロのセルを構成することと関係しています。

  3. あなたの質問に欠けている部分は、tagsOfCellsオブジェクトをどこに移入するのですか?そのコードは重要です。 cellForRowAtIndexPathにタグを設定しないと、データが同期しなくなり、セルが誤って設定されるように見えます。

次のコードを試してみてください。ここでは別の答えで詳細については

編集

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString* PlaceholderCellIdentifier = @"Cell"; 
    CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier forIndexPath:indexPath]; 
    if (!customCell) 
    { 
     customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
              reuseIdentifier:@"cell"]; 
    } 

    NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row]; 

    if (![self.tagsOfCells containsObject:myNum]) 
    { 
     NSLog(@"Row: %ld",(long)indexPath.row); 
     UIImage *img = [UIImage imageNamed:@"placeholder"]; 
     customCell.realProgressStatus.text = @""; 
     customCell.progressView.progress = 0.1; 
     customCell.image.image = img; 
     [customCell setNeedsLayout]; 
    } 

    customCell.delegate = self; 
    customCell.cellIndex = indexPath.row; 
    customCell.nameOfImage.text = self.names[indexPath.row]; 

    if (indexPath.row % 2 == 0) 
    { 
     customCell.backgroundColor = [UIColor grayColor]; 
    } 
    else 
    { 
     customCell.backgroundColor = [UIColor darkGrayColor]; 
    } 

    return customCell; 
} 

を。セルを構成した後にprepareForReuseが呼び出されていません。 dequeueReusableCellを呼び出すとが呼び出され、のセルが設定されます。私はprepareForReuseが問題であるとは思わない。

+0

お返事ありがとうございます、残念ながらあなたのコードは状況を変更しませんでした。自分の答えを修正しました。ここに私がself.tagsOfCellsを設定する方法が含まれていました。その1つはNSURLConnectionメソッドです。 – Melany

0

インタフェースビルダーのプロトタイプセルを使用していないため、間違ったデキュー再利用可能なセルメソッドを使用しているようです。あなたの状況に合った正しいものにはインデックスパスのパラメータがありません。

CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier]; 

そして、他の人があなたはそれがその前にゼロなので、カスタムセルを初期化ALLOCした後に初期化のあなたの2行を移動する必要が言ったように。たとえば、セルをデキューする必要がない場合、セルをデキューする必要があります。その後、有効なインスタンスを持つセルにパラメータを設定します。

関連する問題