0

dequeueReusableCellWithIdentifier:の方法を使用すると、奇妙な問題が発生しUITableViewます。メソッドを十分に理解していないのか、それとも単純に奇妙なのかはわかりません。ここに行きます:

ユーザーにいくつかのデータを提示する を使用してUITableViewおり、内部では
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath次のように dequeue メソッドを使用しています。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];

contentViewその後、セルのプロパティにいくつかのサブビューを追加します。テーブルを少し下にスクロールすると、以前に追加されたサブビューが表示されます。つまり、セルは空ではなく、「古い」データで満たされています。デキューせず、alloc-init毎回新しいセルを作成すると、セルは空になりますが、メモリ消費量が少し増えます。これは、まさに私が少しダウンさせようとしているものです。それがここで何かを意味する場合、私はARCを使用しています。

何を、またはどのように問題に取り組む必要がありますか? forコンテンツ ビューのサブビューをループしてみまし[view removeFromSuperview]たが、以前のビューが削除され、メモリ消費量が少し減少しました。しかし、それは本当に必要ですか?それとももっと良い方法がありますか?

ここで編集して、サブビューを追加する方法をさらにコードします

cell.backgroundView = [[UIView alloc] initWithFrame:cell.frame];
cell.backgroundColor = kClearColor; //defined to [UIColor clearColor]
cell.selectionStyle = UITableViewCellSelectionStyleNone;

if (indexPath.row == 0)
{
    UIImageView *shine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    shine.image = [UIImage imageNamed:@"top_shine_1"];
    [cell.backgroundView addSubview:shine]; //its a gradient thats why its added to background

    UILabel *appLabel = [[UILabel alloc] initWithFrame:CGRectMake(55, winSize.height * 0.027, 250, 33)];
    appLabel.backgroundColor = kClearColor; //defined to clear color
    appLabel.textColor = kWhiteColor; //defined to white color
    appLabel.text = [viewOrder objectAtIndex:tableView.tag]; //just an array from where I get the required text
    appLabel.font = kStandardFontOfSize(30); //defined to a specific font

    [cell.contentView addSubview:appLabel];

    UIButton *settingsButton = [UIButton buttonWithType:UIButtonTypeCustom];
    settingsButton.frame = CGRectMake(10, winSize.height * 0.0377, 31, 21);
    [settingsButton setImage:[UIImage imageNamed:@"settings_button"] forState:UIControlStateNormal];
    [settingsButton addTarget:self action:@selector(settings:) forControlEvents:UIControlEventTouchUpInside];

    [cell.contentView addSubview:settingsButton];

    return cell; //here I just return it since this is all the config the first cell needs
}

NSString *app = [viewOrder objectAtIndex:tableView.tag];
NSArray *boxes = [[plist secondObjectForKey:@"order" parent:app] componentsSeparatedByString:@";"];

//Add necessary shines or create the last logotype cell - just some details and stuff, all are just images
if (indexPath.row == 1)
{
    UIImageView *shine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 282.5)];
    shine.image = [UIImage imageNamed:@"top_shine_2"];

    [cell.backgroundView addSubview:shine];
}
else if (indexPath.row == 2)
{
    UIImageView *shine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, winSize.width, 150)];
    shine.image = [UIImage imageNamed:@"main_shine"];

    [cell.backgroundView addSubview:shine];
}
else if (indexPath.row == boxes.count + 1)
{
    UIImageView *logo = [[UIImageView alloc] initWithFrame:CGRectMake(111.5, 25, 97, 20)];
    logo.image = [UIImage imageNamed:@"cell_logo"];

    [cell.backgroundView addSubview:logo];
    return cell;
}

NSString *databox = [boxes objectAtIndex:indexPath.row - 1];
UIView *view; //Main subview to be added to the cell

/*
    here I have a class that creates a view with a bunch of subviews added to that view, the view is then assigned to 'view'; kinda like
view = [someAssembler assembleViewWith:options.....]. all are basically UILabels or ImageViews added to the main view
*/

[cell.contentView addSubview:view]; //and here this 'main view' is added as a subview, this view is still visible after the cell has been dequeued and the shines are as well

return cell;

背景とテキストの色に単一の色を使用しない理由を批判する前にUIColor、これはまだテスト段階であることを思い出してください。後で処理されます。

4

1 に答える 1

2

[cell.backgroundView addSubview:shine];これらのコード行が問題です。

cellForRowif (!cell) ブロック内に完全な再利用可能なセルを作成し、呼び出されるたびにセルを再設定する必要があります。一意のセルごとに、一意の再利用識別子を使用する必要があります。たとえば、サブビューのレイアウトが異なるセルが複数ある場合は、それらに異なる識別子を使用する必要があります。

特定の例では、if (indexPath.row == 1)ブロック内にセルを作成する必要があります。

static NSString *cellIdentifier = @"cell";
UITableViewCell *cell = nil;

if (indexPath.row == 0) {
  cellIdentifier = @"topCell";
  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
  if (!cell) {
    // create the cell and add the necessary subviews for indexPath row 0
  }
  return cell;
}
else if (indexPath.row == 1) {

}

//etc.

}

ただし、このアプローチでは !cell ブロッ​​ク内の各セルに対して「メイン サブビュー」を作成する必要があるため、セルのサブクラス化を検討する必要があります。

于 2013-08-24T09:37:18.687 に答える