繁体   English   中英

目标C UITableView无法与自定义单元格和视图平滑滚动

[英]objective c UITableView not scrolling smooth with custom cell & views

我希望tableview在每一行中显示可滚动的多个图像。 为此,我使用UITableViewCustom UITableViewCell ,在自定义tableView单元格中,我正在生成具有多个视图和图像的滚动视图,因此,当我滚动表格时,其滚动不会平稳地闪烁。 谁能建议我以更好的方式做到这一点?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
   // Products table view. 
   ProductCustomCell *cell = (ProductCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CatelogCell"] ;//] forIndexPath:indexPath]; 
   if (cell == nil) { 
      cell = [[ProductCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CatelogCell"]; 
   } 
   cell.productCellDelegate = self; 
   [cell initProperties]; 
   [cell showProductsInScroll:catelogBundle];
}

如果要平滑地滚动tableview,则应注意一些技巧。

  1. 缓存行的高度(表视图可以经常请求),实际上,这并不是阻止表视图滚动的关键点。

  2. 为表中使用的图像创建最近最少使用的缓存(并在收到内存警告时使所有不活动的条目无效)-您可以使用SDWebImage下载图像并缓存它们。 有时,您可能想要缓存一些经常用于表视图的图像,即使当前视图为顶视图,即使您收到内存警告,这些图像也可能无法释放。

  3. UITableViewCelldrawRect:绘制所有内容drawRect:如果可能,不惜一切代价避免使用子视图(或者,如果您需要标准的可访问性功能,则使用内容视图的drawRect: )-可以节省一些成本,但也可能花费更多的时间来编写代码也许很难维护代码。 但是,在uitableviewcell上使用较少的视图确实很好,这将改善您的性能。

  4. 使UITableViewCell的图层不透明(如果有的话,对内容视图也一样)-请尽可能少使用图层不透明。

  5. 使用UITableView示例/文档推荐的reusableCellIdentifier功能-您必须遵循此提示。

  6. 避免未预先烘焙到UIImage的渐变/复杂的图形效果-如第4点。

当然,大多数时候,如果您的表格视图滚动不平滑,则主要问题是您要同步加载图像。

使用仪器测试性能真的很好。

您可能已经为您的问题找到了解决方案,但是如果您仍在寻找,这对我很有用。 我还在开发一个应用程序,该应用程序需要在多个tableview单元格上显示许多图片。

我发现,每次应用程序将一个新的单元cellForRowAtIndexPath载到尚未显示​​的屏幕上时,就会调用cellForRowAtIndexPath方法,因此,每次向上或向下滚动到新单元格时,即使某些滚动到其他位置之前,屏幕上的单元格已显示在屏幕上。

我所做的是将第一次初始化的单元格及其对应的索引路径保存到数组中,并再次调用cellForRowAtIndexPath方法时,通过检查索引路径是否存储在我的索引路径数组中来检查此单元格是否已初始化。

@implementation MyViewController{
    NSMutableArray *cells;
    NSMutableArray *indexpaths;
}

...

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

    // check if in array
    if ([indexpaths containsObject:indexPath]){
        return cells[indexPath.row];
    }

    // otherwise, create a new one
    UITableViewCell *cell = [[UITableViewCell alloc] init];

    // customizing cell
    // other stuff
    ...

    // finally save the cell and indepath for checking later
    [cells addObject:cell];
    [indexpaths addObject:indexPath];

    return cell;
}

我认为问题可能是您可能在UITableView的cellForRowAtIndexPath委托方法中分配对象。 因此,与其分配任何类型的对象,不如在其ProductCustomCell类中分配或在其xib文件中创建它。

除了TinyMonk的答案,我想添加一个简单的方法。 如果使用自定义单元格制作uitableview,请确保在表和自定义单元格上都选中clip subview选项。 它为我工作。

基于Leo C han的解决方案,我已将其更新为Swift3。

var manualCells = NSMutableArray()

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

   // check if in array
   if manualCells.contains(indexPath) {
      return manualCells.object(at: indexPath.row) as! UITableViewCell
   }

   let cell = self.tableViewReference.dequeueReusableCell(withIdentifier: "mainIdentifier") as! YourTableViewCell

   // fill the cell...     

   manualCells.insert(cell, at: indexPath.row)
   return cell
}

注意,这是针对包含一个部分的表的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM