0

私は初心者です。このコードを使用して を作成してUITableViewCellいますが、テーブルをリロードすると、すべてのラベルは正常に機能しますが、ボタンの画像が常に正しいとは限りません。どうしてか分かりません。この問題を解決するにはどうすればよいですか?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];

        UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
        FileNameLabel.tag = 1000;
        FileNameLabel.backgroundColor = [UIColor clearColor];
        FileNameLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
        FileNameLabel.textColor = [UIColor blackColor];
        [cell.contentView addSubview: FileNameLabel];
        [FileNameLabel release];


        UILabel *UploadTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 150, 25)];
        UploadTimeLabel.tag = 2000;
        UploadTimeLabel.backgroundColor = [UIColor clearColor];
        UploadTimeLabel.font = [UIFont fontWithName:@"Helvetica" size:12];
        UploadTimeLabel.textColor = [UIColor grayColor];
        [cell.contentView addSubview: UploadTimeLabel];
        [UploadTimeLabel release];


        UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];
        pricelabel.backgroundColor = [UIColor clearColor];
        pricelabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        pricelabel.font = [UIFont boldSystemFontOfSize:16];
        pricelabel.textColor = [UIColor darkGrayColor];
        pricelabel.tag = 3000;
        //pricelabel.hidden = YES;
        pricelabel.textAlignment = NSTextAlignmentRight;
        [cell.contentView addSubview: pricelabel];
        [pricelabel release];


        market = [[UIButton alloc] init];;
        [market setFrame:CGRectMake(200, 6, 30, 30)];
         market.tag = 4000;

        [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];


        [cell.contentView addSubview:market];
   }

    if( [temp count] > 0)
    {
        UILabel *fileNameLbl = (UILabel*)[cell.contentView viewWithTag:1000];
        fileNameLbl.text =[temp objectAtIndex:indexPath.row];

        UILabel *uploadlbl = (UILabel*)[cell.contentView viewWithTag:2000];
        uploadlbl.text =[UploadTimeAllArr objectAtIndex:indexPath.row];
    }

    UIButton *marketButton = (UIButton*)[cell.contentView viewWithTag:4000];
    [marketButton setTag:indexPath.row];
    if([sellingArray count]>0)
    {
        NSLog(@"sellingArray %@",sellingArray);
        if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"0"]) // nothing
        {

            [marketButton setSelected:NO];
            [marketButton setImage:[UIImage imageNamed:@"Marketplace.png"] forState:UIControlStateNormal];
            marketButton.enabled = YES;

        }
        else if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"2"])  // marketplace
        {

            [marketButton setSelected:YES];
            [marketButton setImage:[UIImage imageNamed:@"MarketplaceSelect.png"] forState:UIControlStateNormal];
            marketButton.enabled = YES;

        }
    }


    return cell;
}
4

3 に答える 3

1

ここでの主な問題は、このメソッドが呼び出されるたびにセルに新しいビューを再作成していることです。内部にすべての再利用可能な要素を作成する必要がありますif(cell == nil)。そうしないと、重複が発生します。動的なものはすべて、この外部で作成する必要があります。私はあなたのコードを取り、それを修正しました。これはうまくいくはずです。

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        // Everything that does not change should go in here!

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        UILabel *pricelabel = [[UILabel alloc] initWithFrame:CGRectMake(80, 0, 80, 30)];


        pricelabel.backgroundColor = [UIColor clearColor];
        pricelabel.font = [UIFont fontWithName:@"Helvetica" size:16];
        pricelabel.font = [UIFont boldSystemFontOfSize:16];
        pricelabel.textColor = [UIColor darkGrayColor];
        pricelabel.tag = 3000;
        //pricelabel.hidden = YES;
        pricelabel.textAlignment = NSTextAlignmentRight;
        [cell addSubview:pricelabel];

        UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
        [market setFrame:CGRectMake(200, 6, 30, 30)];
        [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];
        [cell addSubview:market];
    }

    // find market button, since we could be reusing a cell we cannot rely on a tag
    // value to find it. (This would only work with one button though).
    UIButton *market;
    for (UIView *subview in cell.subviews) {
    if ([subview isKindOfClass:[UIButton class]]) {
            market = (UIButton *)subview;
            break;
        }
    }

    // set all defaults in case of reuse
    [market setImage:[UIImage imageNamed:@"DefaultImage.png"] forState:UIControlStateNormal];
    market.selected = YES;
    market.enabled = NO;
    market.clearsContextBeforeDrawing = NO;

    if([sellingArray count] > 0) {
        NSLog(@"sellingArray %@",sellingArray);
        if([[sellingArray objectAtIndex:indexPath.row] isEqualToString:@"0"]) {
            // not sure if this is supposed to be YES or NO
            market.clearsContextBeforeDrawing = YES;
            [market setSelected:NO];
            [market setImage:[UIImage imageNamed:@"Marketplace.png"] forState:UIControlStateNormal];
            market.enabled = YES;
        }
    }
    [market setTag:indexPath.row];

    return cell;
}

ARC を使用していないように見えるので、必要な参照カウントがないかこのコードを確認してください。

于 2013-08-19T15:51:42.063 に答える
0

2 番目の編集:

これは上記の回答からコピーされました:

メソッド内-cellForRowAtIndexPath:

    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellSubtitle];
        UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
            [market setFrame:CGRectMake(200, 6, 30, 30)];
        [market addTarget:self action:@selector(marketPressedAction:)     forControlEvents:UIControlEventTouchDown];

        [cell.contentView addSubview:market];

    //Add all your UILabel INITIATION stuff here as well

    }

    UIButton *marketButton;
    for (UIView *subview in cell.subviews) {    
        if ([subview isKindOfClass:[UIButton class]]) {
            marketButton = (UIButton *)subview;
            break;        
        }    
    }
    marketButton.tag = [indexPath row];

    UILabel *priceLabel = [cell.contentView viewWithTag:3000];
    UILabel *uploadTimeLabel = [cell.contentView viewWithTag:2000];

    //Set up your labels and button now

    return cell;
}


    EDIT: Leaving my original answer below for posterity but I see that you are setting the table index row as the MarketButton's tag. If you're using that to figure out which dataSource object to query, this is bad practice. You should be making a custom cell which can hold a reference to the object in your data source, so you don't have to ask the button for its tag, and then ask the data source array for the object at index:tag. 

これが悪い理由は、どこかで配列の状態が変わる可能性があるためですが、表のセルはまだ表示されており、間違ったインデックスを指すタグが保持されています。セルに問題のオブジェクトを追跡させるだけの場合、配列構造に何が起こっても、必要なオブジェクトを変更することが保証されます。

Firoの答えについて私が変更する唯一のことは、セル内の各ビューに「タグ」プロパティを追加するだけなので、見つけるたびに繰り返す必要はありません.

また[[UIButton alloc]init]、不要であり、ダングリング ポインターと見なされる可能性があるため、行を削除しました。

if (cell == nil) {
    // Everything that does not change should go in here!

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    UIButton *market = [UIButton buttonWithType:UIButtonTypeCustom];
    [market setFrame:CGRectMake(200, 6, 30, 30)];
    [market addTarget:self action:@selector(marketPressedAction:) forControlEvents:UIControlEventTouchDown];

    market.tag = 9999;

    [cell.contentView addSubview:market];
}

//don't have to do UIView iteration here
UIButton *marketButton = [cell.contentView viewWithTag:9999];
于 2013-08-19T16:04:51.513 に答える
0

dequeReusablecellWithIdentifier:メソッドは、既に作成されセル インスタンスを返します。参照がまだ nil を指している場合は、有効なセルが必要であり、そのメソッドから返されるセルを 1 つ作成しますcellForRowatIndexpath:。したがって、すべての設定はカスタムであり、すべてここで行う必要があります。(cell ==nil)

于 2013-08-20T14:43:08.510 に答える