2

UITableViewの特定のセルにのみ画像を表示しようとしています。これが私のconfigureCellメソッドです:

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
    UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
    UIImageView *ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
    [ribbonView setImage:ribbon];
    [cell addSubview:ribbonView];
    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}

そしてここにcellForRowAtIndexPathがあります:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // set up the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

の値に関係なく、最初はすべてのセルがそれらをribbonViewで描画するため、これは完全には機能しませんinfo.visited。if / elseをステップスルーしましたが、非表示のコードがヒットしていることがわかります。ただし、リストから移動して戻った場合は、正しいリボンの状態が表示されます。テーブルビューをスクロールすると、再び壊れます。

ただし、フォントの色は常に正しいです。

4

3 に答える 3

5

セルを再利用している場合は、セルに複数のサブビューを追加している可能性があります。そのため、現在のがのribbonView場合でも、セルには別のribbonViewが残っており、引き続き表示されます。info.visitedindexPathNO

やるべきことは、ribbonViewサブビューが1つしかないことを確認することです。これはribbonViews、構成メソッドで古いものを削除するか、セルにプロパティをサブクラスUITableViewCell化して追加することで実行できます。ribbonViewこのプロパティは一度設定され、セルのビュー階層に追加されます。一度、これにアクセスして、構成メソッドにhiddenNOまたはYES構成メソッドで設定できます。

UILabel編集:セルのビュー階層にある1つのインスタンスの色を変更しているため、セルのテキストの色は常に正しいものになります。UILabel代わりに、構成メソッドが構成されるたびにセルに新しいサブビューを追加した場合、同じバグのある動作が見られると思います。

編集:試すコード

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    static NSInteger ribbonTag = 12345;
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
    // re-use a ribbonView if one's already been added to this cell
    UIImageView *ribbonView = [cell.contentView viewWithTag:ribbonTag];
    if (!ribbonView){
       ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
       ribbonView.tag = ribbonTag;
       UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
       [ribbonView setImage:ribbon];
       // add subviews to contentView
       [cell.contentView addSubview:ribbonView];
    }
    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}
于 2013-03-16T16:41:59.847 に答える
1

メソッドで使用dequeueReusableCellWithIdentifier:forIndexPath:しているtableView:cellForRowAtIndexPath:場合。セルを再利用するたびに、新しいUIImageViewを作成し、最後のセルの上に配置します。

しかし、これを解決するためにサブクラス化する必要はありません。あなたの細胞はまだ単純なので、まだです。さらにサブビューを追加する場合は、サブクラス化が唯一のオプションです。

私が考えることができる1つの解決策はこれです:

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];

    UIImageView *ribbonView = nil;

    //My code:
    for ( UIView *childView in cell.subviews ) {
        if([childView isKindOfClass:[UIImageView class]] {
            ribbonView = childView;
            break;
        }
    }
    //Note: this doesnt work if you have more than one UIImageView in your cell. 
    if(ribbonView == nil) {
        UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
        ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
        [ribbonView setImage:ribbon];
        [cell addSubview:ribbonView];
    }
    //Ends here.

    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}

それを試して、それが機能するかどうか教えてください。

幸運を。

于 2013-03-16T17:20:41.717 に答える
0

それは間違いなくの実装における問題です

tableView:cellForRowAtIndexPath:

あなたは常に電話する必要があります

dequeueReusableCellWithIdentifier:forIndexPath:

次に、configureメソッドを呼び出します

configureCell:atIndexPath:(NSIndexPath *)indexPath

編集:

[cell.contentView addSubView:...]また、 [cell addSubView:...]の代わりに行う必要があると思います

于 2013-03-16T16:55:45.767 に答える