自定义 UITableViewCell 创建了两次......让我发疯

Posted

技术标签:

【中文标题】自定义 UITableViewCell 创建了两次......让我发疯【英文标题】:Custom UITableViewCell Created Twice ... Driving me mad 【发布时间】:2012-03-24 11:53:20 【问题描述】:

我创建了一个自定义 UITableViewCell,我想在单元格上按下按钮时动态扩展和收缩。该方法在按下按钮时被调用,但似乎单元格被创建了两次......因此重置状态......我已经为此倾注了几天尝试不同的事情,但我不知道什么错了……

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

static NSString *CellIdentifier = @"CategoryCell";

// Create a new Cell if necessary

CategoryCell *cell = (CategoryCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];    

if (cell == nil) 
    cell = [[CategoryCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    cell.frame = CGRectMake(0.0, 0.0, 320.0, 67.0);

    NSLog( @"Cell Creation - Row %d", indexPath.row );

    [cell.expandContractButton addTarget:self action:@selector(expandContractButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

else 
    NSLog( @"Cell Found - Row %d", indexPath.row );


// Setup the cell ...

日志....

2012-03-24 11:44:02.158 Review Writer[13523:fb03] Number of rows 1
2012-03-24 11:44:02.172 Review Writer[13523:fb03] Cell Creation - Row 0
2012-03-24 11:44:02.192 Review Writer[13523:fb03] Row 0 - setting height
2012-03-24 11:44:02.197 Review Writer[13523:fb03] Cell Creation - Row 0

关于为什么会出现这种情况的任何指针?

填充单元格数据的代码

-(void)tableView:(UITableView *)tableView willDisplayCell:(CategoryCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

NSLog(@"Setting up cell on Row %d - Expanded - %@", indexPath.row, cell.expanded ? @"YES" : @"NO");

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Category *cat = [categoryList objectAtIndex:indexPath.row];

cell.categoryLabel.text = cat.category;
cell.ratingLabel.text = cat.overall_rating;

if (cell.expanded == YES)

    [cell expandCell];

else 
    [cell collapseCell];


cell.reviewText.text = cat.review_text;

if([cat.overall_rating isEqualToString:@"Not Rated"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"0_stars.png"]];


if([cat.overall_rating isEqualToString:@"Unsatisfactory"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"1_stars.png"]];


if([cat.overall_rating isEqualToString:@"Needs improvement"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"2_stars.png"]];


if([cat.overall_rating isEqualToString:@"Meets job requirements"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"3_stars.png"]];


if([cat.overall_rating isEqualToString:@"Exceeds job requirements"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"4_stars.png"]];


if([cat.overall_rating isEqualToString:@"Outstanding"])
    [cell.ratingImage setImage:[UIImage imageNamed: @"5_stars.png"]];
    

// Put the accessory disclosure button on the cell

cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

设置单元格高度的代码...

- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath

// Use the method that you would have created above to get the cell.

CategoryCell *cell = (CategoryCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];

NSString *text = cell.reviewText.text;

// Note the 30 is a fudge factor... :-) Otherwise it does not include the last line...

CGFloat width = [cell.reviewText frame].size.width - 30;

CGFloat height = [text sizeWithFont:cell.reviewText.font constrainedToSize:CGSizeMake(width, 9999) lineBreakMode:UILineBreakModeWordWrap].height;

NSLog( @"Row %d - setting height - Expanded = %@", indexPath.row, cell.expanded ? @"YES" : @"NO" );

if (cell.expanded == NO)

    height = 0;


return height + 67; 

展开/折叠单元格的代码...

- (IBAction) expandContractButtonPressed:(id) sender

CategoryCell *clickedCell = (CategoryCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];

CategoryCell *cell = (CategoryCell*)[self tableView:self.tableView cellForRowAtIndexPath:clickedButtonPath];

NSLog( @"EXPAND / COLLAPSE Row %d Exanded = %@", clickedButtonPath.row, clickedCell.expanded ? @"YES" : @"NO");

if (clickedCell.expanded == YES)

    NSLog( @"Collapse" );
    [cell collapseCell];
    clickedCell.expanded = NO;

else 
    NSLog( @"Expand" );
    [cell expandCell];
    clickedCell.expanded = YES;


NSLog( @"Expanded after = %@", clickedCell.expanded ? @"YES" : @"NO" );

NSArray *indexPaths = [[NSArray alloc] initWithObjects:clickedButtonPath, nil];

[self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:NO];

【问题讨论】:

让我猜一猜,也许你以某种方式向 UITableView 发送了 reloadData 或其他一些 reload 消息? CategoryCell 是否带有 .xib 文件?请发布此课程,您发布的代码不足以识别此问题。 CategoryCell 确实使用 XIB 启动,然后我转换为以编程方式创建... 我确实调用了 [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:NO];当按下单元格展开/折叠按钮时......但这似乎再次调用单元格创建两次 伙计们解决了在数据存储中存储展开状态的问题,因此当重新创建单元格时,数据和状态存储在单元格之外......这有点道理。 【参考方案1】:

只是一个猜测,因为您只提供了一小部分代码:也许您有多个部分。您只检查行,而不是部分,因此可以为每个部分调用代码。

【讨论】:

【参考方案2】:

尽管如此,您的代码应该仍然能够处理这种情况(多次创建)并正确显示单元格。

您没有向我们展示设置单元格高度和内容的代码。

你应该没事的。如果您在cellForRowAtIndexPath: 中只保留单元格创建代码 并将所有单元设置代码移动到willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

【讨论】:

为指针干杯...我已经移动我的代码来设置单元格的内容,如上所述。我还在上面的帖子中包含了我的代码的其他部分... 您能否也发布一个更长的日志(来自您的 NSLogs)?为了。例如,当您尝试展开/折叠单元格时...

以上是关于自定义 UITableViewCell 创建了两次......让我发疯的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 自定义 AuthenticationProvider 验证方法调用了两次

nextjs 自定义响应检测钩子调用了两次

Wordpress 自定义 CSS 添加了两次?

为啥我的 UIViewController 被加载了两次? IOS 7

iOS - drawRect:调用了两次

RequestImage 的结果处理程序调用了两次