通过cell.contentView添加一个UIView到UITableViewCell

我有一个名为GraphView的类,它扩展了UIView,它基本上绘制了一个小的折线图。 我需要在我的UITableView的每个部分的顶部的这些图之一。 所以我尝试在我的一个部分的顶部创build一个单独的单元格,然后在那个单元格上做:

[cell.contentView addSubview:graphView]; [graphView release]; 

但是,当我向下滚动时,就像图表出现毛病一样,它沿着UITableView随机出现。 任何人有想法或见解? 有没有更好的方法将另一个UIView合并到我的UITableView的每个部分的顶部?

 - (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //NSLog(@"cellForrowAtIndexPath"); static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; } cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.font = [UIFont systemFontOfSize:12]; cell.detailTextLabel.font = [UIFont systemFontOfSize:12]; NSString *str1, *str2; if(indexPath.section == 0) { if(indexPath.row == 0) { str1 = @""; str2 = @""; S7GraphView *graphView = [[S7GraphView alloc] initWithFrame:CGRectMake(10,0,310,100)]; graphView.dataSource = self; NSNumberFormatter *numberFormatter = [NSNumberFormatter new]; [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; [numberFormatter setMinimumFractionDigits:0]; [numberFormatter setMaximumFractionDigits:0]; graphView.yValuesFormatter = numberFormatter; NSDateFormatter *dateFormatter = [NSDateFormatter new]; [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; [dateFormatter setDateStyle:NSDateFormatterShortStyle]; graphView.xValuesFormatter = dateFormatter; [dateFormatter release]; [numberFormatter release]; graphView.backgroundColor = [UIColor whiteColor]; graphView.drawAxisX = NO; graphView.drawAxisY = YES; graphView.drawGridX = NO; graphView.drawGridY = YES; graphView.xValuesColor = [UIColor blackColor]; graphView.yValuesColor = [UIColor blackColor]; graphView.gridXColor = [UIColor blackColor]; graphView.gridYColor = [UIColor blackColor]; graphView.drawInfo = NO; graphView.info = @"Load"; graphView.infoColor = [UIColor whiteColor]; //When you need to update the data, make this call: //[graphView reloadData]; //S7GraphView *graphView = [[S7GraphView alloc] initWithFrame:CGRectMake(10,0,320,300)]; //self.graphView.dataSource = self; [cell.contentView addSubview:graphView]; [graphView release]; } 

我已经解决了使用标签:

 - (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; } else{ [[cell.contentView viewWithTag:500] removeFromSuperview]; } ... graphView.tag = 500; [cell.contentView addSubview:graphView]; } 

表格视图的工作原理与您最初预期的略有不同。 基本上,只有你看到的单元格实际上被加载到内存中。 如果你仔细想一下,这是有道理的 – 如果你的表中有10,000个项目,所有的项目都被加载到内存中,那么你的应用程序将会耗尽内存,并且会很快崩溃。

当你滚动时,你的单元格是实时创build的。 令人困惑的部分:您的单元格不是从头开始创build的,而是iOS刚刚取出一个刚刚离开屏幕并发送完毕的单元格

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

再次。 因此,当您滚动时,您添加到顶层单元格的子视图将不会被删除。 简短的回答:确保你删除/重置上述函数中的子视图,这样你将'重置'任何使用的单元格,正在进一步向下查看表视图。

为什么iOS这样做呢? 效率 – 基本上,创build一个tableview单元是非常昂贵的。 寻找宽度,颜色,绘制形状… +更多需要大量的CPU功耗和时间。 每次重复使用单元而不是从头开始效率更高。

因此,只需重置单元格创buildfunction中单元格的必要字段。 这样,你将有平滑和快速的滚动,但单元格的视图/属性将被重置,然后重用单元​​格。

一开始感到困惑? 对。 但绝对是更好的方法来做到这一点。

确定这样:

 static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; } //now remove any subview a reused cell might have: [cell.contentView.view removeFromSuperview]; //and in part of the method, you'll need to create the subview if the cell is in the top row. if (indexPath.row == 0) { [cell.contentView.view addSubview:graphView.view]; } 

它可能会略有不同,因为你的情况,而不是一个UIViewgraphics视图。 但这绝对是它应该看起来像的基础。

希望有所帮助!

正如我所想,这是一个细胞重复使用的问题:

每次, tableView:cellForRowAtIndexPath:得到执行,你添加GraphView的另一个实例。 结合细胞重用,细胞对象被重新分配给其他indexPaths,这会导致很大的麻烦。

你应该只在if (cell == nil)里面添加子视图。

你将不得不跟踪或你的GraphViews分开。 可以通过将它们添加到以indexPaths为关键字的NSDictionary中,也可以通过inheritanceUITableViewCell来实现。