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

确保在每次cellForRowAtIndexPath调用中都会重置单元格的状态。您有一堆 if/else 条件,并且控制流使得用于在单元格上设置内容的代码根本不会被调用,这就是为什么来自先前重用单元格的内容仍然存在的原因。

我的规则是在我更改单元格状态的地方始终为 s 提供匹配的 else 条件if(如果没有,则至少为空白)。如果是UITableViewCell子类,您可以在prepareForReuse

于 2014-09-23T15:27:29.617 回答
1

您的问题几乎肯定与表视图回收单元格的事实有关。正如您所说,这就是需要“清除”单元格的原因。

例如,如果您在顶部附近有一个显示图像的单元格,如果您进一步向下滚动并且同一单元格用于显示不应有图像的单元格,则该图像仍会出现,除非您已经从那以后删除它。即使您有 100 个单元格要显示,也可能只有少数实际存在的实例 - 它们会被回收。

话虽如此,即使您没有说仍然出现哪个文本,如果prodnil,它可能是各种对象,包括pNumberand 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 足够长并且用户快速滚动浏览它,会导致大量的 allocs/deallocs,从而导致滚动不流畅。然后总是将行特定代码放在检查单元格为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 回答