0

私は Xcode 4.3 を持っていますが、そのクラスは ARC を使用していません。

再利用可能なセルを使用するテーブルビューを作成しました。私は他の人から答えを得ようとしましたが、適切な答えを得ることができませんでした。

私のテーブルは配列からデータを取得し、データを表示して画像を表示するために使用UILabelします。UIImageView

私のコードは以下です。UILabel長いですが、 、 ボタン、画像を一度作成して配置し、データを変更するという考え方です。

スクロールすると、1 つのセルのみが変更され (スクロール中に別のデータが表示されます)、他の再利用されたセルにはセル 1 の同じデータが表示されます。

static NSString * CellIdentifier = @"HistoryCellId";

iImage = [UIImage imageNamed: [NSString stringWithFormat:@"%@.png",[(_searching ? _titleArrCopy : _titleArr) objectAtIndex:indexPath.row]]];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                  reuseIdentifier:CellIdentifier];
    iconImage = [[UIImageView alloc] init];
    UIImage * image = [UIImage imageNamed:@"HFcellBG.png"];
    UIImageView * bgImage = [[UIImageView alloc] initWithImage: image];
    cell.backgroundView = bgImage;
    //[iconImage removeFromSuperview];
    iconImage.image = iImage;
    iconImage.frame = CGRectMake(_iconX, 11, 58, 58);
    //iconImage.backgroundColor = [UIColor whiteColor];
    [cell addSubview:iconImage]; // show the image on the side

    titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(_titleX, 3, 212, 25)];
    titleLabel.textAlignment = _nibNameRTL ? UITextAlignmentRight : UITextAlignmentLeft;
    [cell addSubview:titleLabel]; // show a title

    timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(_dateX, 25, 212, 20)];
    timeLabel.textAlignment = _nibNameRTL ? UITextAlignmentRight : UITextAlignmentLeft;
    timeLabel.font = [UIFont systemFontOfSize:15]; // show another data
    [cell addSubview:timeLabel];

    favoriteBtn = [[UIButton alloc] initWithFrame:CGRectMake(_removeX, 48, 66, 23)];
    favoriteBtn.titleLabel.font = [UIFont systemFontOfSize:12];
    [favoriteBtn setTitle:getTextValue(3) forState:UIControlStateNormal];
    [cell addSubview:favoriteBtn];
     // show a button

} 

[iconImage setImage:iImage];

[titleLabel setText:[self parserData:indexPath.row]];

[timeLabel setText:[NSString stringWithFormat:getTextValue(4),[(_searching ? _TimeArrCopy :_TimeArr) objectAtIndex:indexPath.row]]];

if ([[(_searching ? _FavoriteArrCopy : _FavoriteArr) objectAtIndex:indexPath.row] isEqualToString:@"1"]) {
    [favoriteBtn setEnabled:NO];
    [favoriteBtn setBackgroundImage:[UIImage imageNamed:@"HFfavoriteCheckedBtn.png"] forState:UIControlStateNormal];
}
else {
    [favoriteBtn setEnabled:YES];
    [favoriteBtn setBackgroundImage:[UIImage imageNamed:@"HFfavoriteBtn.png"] forState:UIControlStateNormal];
}

favoriteBtn.tag = indexPath.row;
[favoriteBtn addTarget:self action:@selector(addToFavorite:) 
      forControlEvents:UIControlEventTouchUpInside];


//    [cell.favoriteBtn setTitle:getTextValue(3) forState:UIControlStateNormal];
//    [cell.typeImage setImage:iconImage];
//    cell.data = [_dataArr objectAtIndex:indexPath.row];

cell.selectionStyle = UITableViewCellSelectionStyleNone;
// return it
return cell;

}

データは次のようになります: 毎回 5 つのセルが表示され、スクロールすると以下の動作が見られます。

1
2
3
4
5 - the cell 5 changes all the time while scrolling
1 - cell one data again
2
etc

を確認するindexPath.rowと、右の行です。

どうしたの?

4

1 に答える 1

0

セルを構成するために使用しようとしている変数は、if チェック内で初期化されますが、これはおそらく true ではありません (特にスクロール後、セル インスタンスが既に存在する場合)。状態を変更するには、セル オブジェクトのプロパティにアクセスする必要があります。

これは、nil にメッセージを送信できるようにする Objective-C の落とし穴の 1 つです。

[titleLabel setText:[self parserData:indexPath.row]];

スクロールすると titleLabel は nil になり、エラーは発生しません。

セルに多くのカスタム UI がある場合は、カスタム サブクラスを作成し、カスタマイズする必要があるすべてのサブビューのプロパティを追加してから、これらのプロパティを if(cell == nil) ブロックの外で使用することをお勧めします。

于 2012-06-18T18:50:34.173 に答える