UITableviewCell отображать текст для другой ячейки при прокрутке
Когда я прокручиваю свои пользовательские 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;
}
3 ответа
Ваша проблема почти наверняка связана с тем, что табличные представления перерабатывают ячейки. Вот почему клетки должны быть "очищены", как вы выразились.
Например, если у вас есть одна ячейка вверху с отображаемым изображением, если вы прокручиваете ее вниз и эта же ячейка используется для отображения ячейки, в которой не должно быть изображения, это изображение будет отображаться, если только вы не удалил его с тех пор. Даже если у вас было 100 ячеек для отображения, вероятно, существует только несколько экземпляров, которые действительно существуют - они перерабатываются.
При этом, даже если вы не сказали, какой текст все еще появляется, если prod
является nil
, это могут быть различные объекты, в том числе pNumber
а также description
, То же самое касается, если self.order.orderOrderCustomer
является 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
,
Убедитесь, что состояние ячейки сбрасывается в каждом cellForRowAtIndexPath
вызов. У вас есть несколько условий if / else, и поток управления таков, что код для установки содержимого в ячейке вообще не вызывается, поэтому содержимое из ранее использованной ячейки остается.
Мое правило - всегда иметь подходящие условия для if
где я изменяю состояние ячейки (если ничего, то хотя бы пусто). В случае UITableViewCell
подклассы, вы можете сбросить состояние в prepareForReuse
Обычно лучше использовать один и тот же идентификатор для всех ячеек, если существуют сотни записей, чтобы ячейки могли повторно использовать память. В противном случае, если просмотр таблицы достаточно длинный и пользователь быстро его прокручивает, это приведет к большому количеству allocs / deallocs, что приведет к не плавной прокрутке. Затем всегда помещайте специфический для строки код вне условия, которое проверяет ячейку на ноль.
Посмотрите на этот фрагмент кода:
-(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;
}