iPhone: добавление подпредставлений в Cell ContentView перезаписывает тексты ячеек при прокрутке
Я использовал Cell.ContentView в моей реализации для настройки содержимого ячейки. Это работает нормально, но единственная проблема в том, что когда у меня много ячеек, и я прокручиваю их вверх и вниз, содержимое ячеек перезаписывается в ячейки, которые просто становятся скрытыми, а затем видимыми. Предположим, что я прокручиваю первую ячейку вверх, а затем снова снимаю ее, содержимое последней ячейки перезаписывается в первой ячейке!!
Я достаточно отладил это, но не смог найти точное решение. Я попытался проверить количество Cell.ContentView.SubViews и, если оно 0, добавить только другие подпредставления. Это не отображает содержимое ячеек, пока я не прокручиваю их вверх и вниз, но как только содержимое появилось, оно не перезаписывается.. Немного странно...!! Я также убедился, что я использую правильное повторное использование клетки. Ниже приведен мой код, который добавляет подпредставления в представление содержимого ячейки. Пожалуйста, дайте мне знать, как я могу избавиться от этой проблемы.
PS: не беспокойтесь о переменных и вычислениях, которые я сделал. Предположим, что он возвращает правильные значения.:)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;
UILabel *textLabel = nil;
textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
textLabel.numberOfLines = 2;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.textAlignment = UITextAlignmentLeft;
textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
if ([textLableColor scanHexInt:&hex]) {
textLabel.textColor = UIColorFromRGB(hex);
}
textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]];
[cell.contentView addSubview:textLabel];
textLabel.backgroundColor = [UIColor clearColor];
lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
UILabel *detailTextLabel = nil;
detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
detailTextLabel.numberOfLines = 2;
detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
detailTextLabel.textAlignment = UITextAlignmentLeft;
detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
if ([detailTextLableColor scanHexInt:&hex]) {
detailTextLabel.textColor = UIColorFromRGB(hex);
}
detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
[cell.contentView addSubview:detailTextLabel];
detailTextLabel.backgroundColor = [UIColor clearColor];
return cell;
}
Благодарю.
5 ответов
Это потому, что игрушка снова и снова добавляет вид на вашу камеру.
Вы должны добавлять их только при создании ячейки и просто устанавливать метки при повторном использовании ячейки.
Вы можете установить теги для вашего ярлыка, чтобы потом можно было установить его текст. Код ниже делает свое дело
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if(style == UITableViewCellStyleValue1)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
else
cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellIdentifier] autorelease];
NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;
UILabel *textLabel = nil;
textLabel.tag = 1;
textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
textLabel.numberOfLines = 2;
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.textAlignment = UITextAlignmentLeft;
textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
if ([textLableColor scanHexInt:&hex]) {
textLabel.textColor = UIColorFromRGB(hex);
}
textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]];
[cell.contentView addSubview:textLabel];
textLabel.backgroundColor = [UIColor clearColor];
lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
UILabel *detailTextLabel = nil;
detailTextLabel.tag = 2;
detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
detailTextLabel.numberOfLines = 2;
detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
detailTextLabel.textAlignment = UITextAlignmentLeft;
detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
if ([detailTextLableColor scanHexInt:&hex]) {
detailTextLabel.textColor = UIColorFromRGB(hex);
}
detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
[cell.contentView addSubview:detailTextLabel];
detailTextLabel.backgroundColor = [UIColor clearColor];
} else {
UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
UILabel *detailTextLabel = (UILabel *)[cell viewWithTag:2];
detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
}
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
Удостоверься что dequeueReusableCellWithIdentifier
а также reuseIdentifier
должно быть nil
Теперь это будет работать!!
Поместите все содержимое пользовательского интерфейса внутри if(cell==nil){uilabel,uilabel или что-нибудь связанное с UI} ... так как пользовательский интерфейс должен вызываться только один раз во время создания cel
Для ясности, ваша проблема в том, что когда вы прокручиваете ячейку в поле зрения, вы часто будете сталкиваться с текстом новой ячейки, записываемой поверх ячейки, которая была только что прокручена за пределами экрана?
Проблема в том, что dequeueReusableCellWithIdentifier:
не "очищает" ячейку (она вызывает prepareForReuse
, но это все), так что все ваши старые подпредставления все еще на месте. Если вы собираетесь повторно использовать ячейки, вам не следует каждый раз воссоздавать эти подпредставления. Вместо этого просто настройте свойства существующих подпредставлений в ячейке, из которой вы вернулись dequeueReusableCellWithIdentifier:
и только создавать новые подпредставления в только что выделенной ячейке. Подклассы UITableViewCell могут помочь в этом как для предоставления свойств /ivars, в которых можно хранить ссылки на эти подпредставления, так и для организации кода, более приятного за счет перемещения создания подпредставлений и обновления в соответствующие методы. Или вы можете просто не использовать ячейки повторно, передав nil для идентификатора повторного использования.
Наиболее вероятная причина того, что он не отображал контент до тех пор, пока вы не прокрутите вверх и вниз, состоит в том, что вновь созданная ячейка может иметь предоставленное платформой текстовое поле и представление изображения, которое затем может быть удалено, если каркас определит, что вы не ' на самом деле их использую.
В iOS5 UILineBreakModeWordWrap
устарела. Вы должны использовать NSLineBreakByWordWrapping
вместо.
Это изменит ваш код, чтобы выглядеть detailTextLabel.lineBreakMode = NSLineBreakByWordWrapping
а также textLabel.lineBreakMode = NSLineBreakByWordWrapping
,