1

カスタム UITableviewCells をスクロールすると、間違ったコンテンツ (別のセルのテキスト) が表示されます。これはランダムに発生します。セルをクリアしようとしましたが、空白のセルが表示されます。私のコードは以下です。誰が何が起こっているのか教えてもらえますか。ここや他の場所から、セルをクリアする必要がある多くの記事を読みましたが、どの時点でデータをクリアするのかよくわからないため、うまくいきませんでした。セルのクラスに prepareForReuse を実装しようとしましたが、うまくいきませんでした。

- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self.products count] == 0) {
        UITableViewCell *cell = [[UITableViewCell alloc] init];
        return cell;
    }

    static NSString *CellIdentifier = @"AvailableCustomerProductCell";

    AvailableCustomerProductTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell.accessoryType = UITableViewCellAccessoryNone;

    cell.buttonAdd.tag = indexPath.row;
    [cell.buttonAdd addTarget: self action: @selector(addToSelectedProduct:) forControlEvents: UIControlEventTouchUpInside];

    Product *prod = nil;
    if (theTableView == self.searchDisplayController.searchResultsTableView) {
        prod = (Product *)[self.filteredProducts objectAtIndex:indexPath.row];
    } else {
        prod = (Product *)[self.products objectAtIndex:indexPath.row];
    }

    if (prod != nil) {
        cell.pNumber.text = prod.number;
        cell.description.text = prod.desc;

        if ([Common getProductPromotion:prod] != nil)  {
            cell.btnPromotionTag.hidden = NO;
            cell.btnPromotionTag.tag = indexPath.row;
            [cell.btnPromotionTag addTarget: self action: @selector(showPromotionDetails:) forControlEvents: UIControlEventTouchUpInside];
        }
        else{
            cell.btnPromotionTag.hidden = YES;
        }

        //Get the customer product price, first:
        //If if the product has a record in the productCustomerPrices list
        //if not get the price from the standard price.

        if (self.order.orderOrderCustomer != nil) {
            CustomerPrice *custPrice = [Common getPriceForCustomer:self.order.customerRef forProduct:prod.productId];

            if (custPrice != nil) {
                //get the customer price
                [cell.btnPrice setTitle:[Common getCurrencyFormattedStringFromFloat:[custPrice.price floatValue]] forState:UIControlStateNormal];
                [cell.btnPrice setTitleColor:[UIColor colorWithRed:0.01 green:0.65 blue:0.77 alpha:1] forState:UIControlStateNormal];
                cell.btnPrice.enabled = NO;
            }else{
                //get the standard price
                float price =[[Common  GetProductStandardPrice:prod.productStanddardPrices ByQuantity:[NSNumber numberWithInt:1]] floatValue];
                [cell.btnPrice setTitle: [Common getCurrencyFormattedStringFromFloat:price] forState:UIControlStateNormal ];
                [cell.btnPrice setTitleColor:[UIColor colorWithRed:1.0 green:0.39 blue:0.0 alpha:1] forState:UIControlStateNormal];
                cell.btnPrice.tag = indexPath.row;
                [cell.btnPrice addTarget: self action: @selector(showStandardPrices:) forControlEvents: UIControlEventTouchUpInside];
                cell.btnPrice.enabled = YES;
            }
        }
    }

    UISwipeGestureRecognizer* sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(cellSwiped:)];
    [sgr setDirection:UISwipeGestureRecognizerDirectionRight];
    [cell addGestureRecognizer:sgr];

    return cell;
}
4

3 に答える 3

1

あなたの問題は、テーブルビューがセルをリサイクルするという事実にほぼ確実に関連しています。あなたが言うように、それが細胞を「クリア」する必要がある理由です。

たとえば、上部近くに画像が表示されているセルが 1 つある場合、さらに下にスクロールし、同じセルを使用して画像を表示しないセルを表示すると、その画像は表示されます。それ以来それを削除しました。表示するセルが 100 個ある場合でも、実際に存在するインスタンスはおそらくほんの一握りで、リサイクルされます。

そうは言っても、どのテキストがまだ表示されているかはわかりませんがprod、 がである場合nil、 や を含むさまざまなオブジェクトである可能性がありpNumberますdescription。同じことが if self.order.orderOrderCustomerisにも当てはまりますnil。このようなことを避けるために、 を取得した直後に次のようなものを置くことができますcell:

cell.pNumber.tex = @"";
cell.description.text = @"";
//etc

別の注意: セルのbuttonAddボタンにターゲットを追加しています。その前の行の既存のアクションを削除する必要があります。例えば:

[cell.buttonAdd removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[cell.buttonAdd addTarget: self action: @selector(addToSelectedProduct:) forControlEvents: UIControlEventTouchUpInside];

btnPromotionTagとについても同様btnPriceです。

于 2014-09-23T15:21:35.097 に答える
0

通常、何百ものレコードがある場合は、セルがメモリを再利用できるように、すべてのセルに同じ識別子を使用することをお勧めします。そうしないと、Tableview が十分に長く、ユーザーが高速にスクロールすると、多くの割り当て / 割り当て解除が発生し、スムーズなスクロールができなくなります。次に、セルがnilであることを確認する条件の外に、常に行固有のコードを配置します。

このコード スニペットを見てください。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIdentifier = @"MY_CELL_IDENTIFIER";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        // Everything that is similar in all the cells should be defined here
        // like frames, background colors, label colors, indentation etc.
    }
    // everything that is row specific should go here
    // like image, label text, progress view progress etc.
    return cell;
}
于 2014-09-24T08:53:39.390 に答える