将UIView添加到cell.contentView时出现UITableView性能问题

在我的UITableViewCells上使用一些子视图时遇到性能问题。 我继续滚动后,最终变得非常缓慢。

我正在做的第一步是为每个单元格创build一个通用的UIView ,本质上是创build一个带有阴影的单元格的圆angular效果的白色单元格。 这种performance似乎是正常的,所以我不认为这是罪魁祸首。

在这里输入图像说明

这里是我用来做到这一点的代码:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *NewsCellIdentifer = @"NewsCellIdentifier"; NewsItem *item = [self.newsArray objectAtIndex:indexPath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer]; cell.contentView.backgroundColor = [UIColor clearColor]; UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,100)]; whiteRoundedCornerView.backgroundColor = [UIColor whiteColor]; whiteRoundedCornerView.layer.masksToBounds = NO; whiteRoundedCornerView.layer.cornerRadius = 3.0; whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1); whiteRoundedCornerView.layer.shadowOpacity = 0.5; [cell.contentView addSubview:whiteRoundedCornerView]; [cell.contentView sendSubviewToBack:whiteRoundedCornerView]; cell.layer.shouldRasterize = YES; cell.layer.rasterizationScale = [UIScreen mainScreen].scale; cell.layer.opaque = YES; cell.opaque = YES; } [cell.contentView addSubview:[self NewsItemThumbnailView:item]]; return cell; } 

这是返回graphics和文本的缩略图视图的方法:

 - (UIView *) NewsItemThumbnailView:(NewsItem *)item { UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)]; UIImageView *thumbNail = [[UIImageView alloc] initWithImage:[UIImage imageNamed:item.ThumbNailFileName]]; thumbNail.frame = CGRectMake(10,10, 45, 45); UILabel *date = [[UILabel alloc] init]; date.frame = CGRectMake(10, 53, 45, 12); date.text = item.ShortDateString; date.textAlignment = NSTextAlignmentCenter; date.textColor = [BVColors WebDarkGrey]; CGFloat fontSize = 10.0; date.font = [BVFont Museo:&fontSize]; date.opaque = YES; thumbNail.opaque = YES; thumbNailMainView.opaque = YES; [thumbNailMainView addSubview:thumbNail]; [thumbNailMainView addSubview:date]; return thumbNailMainView; } 

性能问题似乎是当我将缩略图视图添加到单元格时,因为当我注释该行时,我似乎没有它。 缩略图信息是dynamic的,并随每个单元格而改变。 我将不胜感激任何build议,我应该如何做到这一点,而不降低性能。

UITableView将调用tableView:cellForRowAtIndexPath:每次单元进入视图时, dequeueReusableCellWithIdentifier:将重用现有的单元对象(如果可用)。 这两个事实相结合,将您置于每次滚动时的场景中,同样有限数量的单元格对象最终会以越来越多的子视图出现。

正确的方法是创build一个具有thumbnailView属性的自定义UITableViewCell子类。 在该属性的setter中,删除以前的缩略图(如果有),然后将新的缩略图添加到contentView 。 这可以确保您随时只能拥有一个缩略图子视图。

不太理想的方法是将标签添加到从NewsItemThumbnailViewthumbNailMainView.tag = someIntegerConstant )返回的UIView ,然后使用该标签search任何视图并在添加另一个视图之前将其删除:

  // remove old view UIView *oldThumbnailView = [cell.contentView viewWithTag:someIntegerConstant]; [oldThumbnailView removeFromSuperview]; // add new view [cell.contentView addSubview:[self NewsItemThumbnailView:item]]; 

我结束了利用在这个stackoverflowpostfind的解决scheme:

我应该如何添加Subview到cell.contentView?

本质上,当细胞首次初始化时,我正在设置Nishant提到的视图; 然而,一旦单元格被重用,我将提取出需要更改的项目,例如UIImageView,然后是UILabel。 既然这些是指针,我可以修改我需要的时候需要的东西,而且性能又快了。 这是我所做的一个缩写版本。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *NewsCellIdentifer = @"NewsCellIdentifier"; NewsItem *item = [self.newsArray objectAtIndex:indexPath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer]; UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)]; UIImageView *thumbNail; UIView *textMainView = [[UIView alloc] initWithFrame:CGRectMake(20,20,80,80)]; UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(52,-5, 70, 20)]; UILabel *teaserLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,20, 210, 40)]; UIView *newsItemCornerMainView = [[UIView alloc] initWithFrame:CGRectMake(255.7, 55.2, 55, 55)]; UIImageView *cornerIconView; // If the cell doesn't existing go ahead and make it fresh. if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer]; // Configure all the various subviews ..... //Sample below // Make the title view headerLabel.text = item.Title; CGFloat textfontSize = 16.0f; headerLabel.font = [BVFont Museo:&textfontSize]; headerLabel.textColor = [BVColors WebBlue]; headerLabel.textAlignment = NSTextAlignmentLeft; headerLabel.numberOfLines = 0; headerLabel.tag = 50; // Make the Teaser view teaserLabel.text = item.Teaser; teaserLabel.numberOfLines = 0; CGFloat tfontSize = 13.0f; teaserLabel.textAlignment = NSTextAlignmentLeft; teaserLabel.textColor = [BVColors WebDarkGrey]; teaserLabel.font = [BVFont HelveticaNeue:&tfontSize]; [teaserLabel sizeToFit]; teaserLabel.tag = 51; [textMainView addSubview:headerLabel]; [textMainView sendSubviewToBack:headerLabel]; [textMainView addSubview:teaserLabel]; [cell.contentView addSubview:textMainView]; .... } thumbNail = (UIImageView *) [cell viewWithTag:47]; [thumbNail setImage:[UIImage imageNamed:item.ThumbNailFileName]]; headerLabel = (UILabel *) [cell viewWithTag:50]; headerLabel.text = item.Title; teaserLabel = (UILabel *) [cell viewWithTag:51]; teaserLabel.text = item.Teaser; cornerIconView = (UIImageView *) [cell viewWithTag:48]; [cornerIconView setImage:[UIImage imageNamed:item.CornerIconFileName]]; return cell; } 

您应该每次只更改thumbNailMainView内容,但不应每次都将其内容添加到单元格中。

所以添加这一行你分配单元格

  [cell.contentView addSubview:[self NewsItemThumbnailView:item]]; 

在括号内加上这个。 然后从单元格访问thumbNailMainView并传递需要为每个单元格更改的项目数据。

thumbNailMainView及其子视图thumbNail分配标签,然后将其作为

  UIView *_thumbNailMainView = [cell.contentView viewWithTag:_thumbNailMainView_tag]; UIImageView *_thumbNail = [_thumbNailMainView viewWithTag:thumbNail_tag]; _thumbNail.image = [UIImage imageNamed:item.ThumbNailFileName]; 

希望它可以帮助你。