objective c UITableView无法使用自定义单元格和平滑滚动意见

时间:2014-01-22 10:20:36

标签: ios iphone objective-c ios5 ios7

我希望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];
}

5 个答案:

答案 0 :(得分:5)

如果你想平滑滚动tableview,你应该注意几个提示。

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

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

  3. 如果可能的话,在UITableViewCell drawRect:中绘制所有内容,不惜一切代价避免使用子视图(或者如果您需要标准辅助功能,内容视图的drawRect:) - 它可以节省一些成本,但它也可能花费你更多的时间来编码,也许很难维护代码。但是在uitableviewcell上使用较少的视图真的很好,这会提高你的表现。

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

  5. 使用UITableView示例/文档中建议的reusableCellIdentifier功能 - 你必须遵循这个提示。

  6. 避免使用未预先加入UIImage s的渐变/复杂图形效果 - 比如第4点。

  7. 当然,大多数时候,如果你的tableview滚动不顺畅,主要问题是你在同步中加载图像。

    使用仪器测试性能非常好。

答案 1 :(得分:1)

你可能已经找到了解决问题的方法,但如果你还在寻找,这对我有用。我还在开发一个应用程序,它涉及在几个tableview单元格上显示许多图片。

我发现每次应用程序将新单元格加载到尚未显示​​的屏幕上时,都会调用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;
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

除了TinyMonk的回答,我想添加一个简单的方法。如果您使用自定义单元格进行uitableview,请确保为表格和自定义单元格选中剪辑子视图选项。它对我有用。

答案 4 :(得分:0)

根据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
}

注意,这适用于包含一个部分的表。