tableView:cellForRowAtIndexPath:不仅为可见单元格调用?

pee*_*onn 8 uitableview ios

我有一个tableView与部分,可以打开和关闭.因此,当我点击一个部分打开它时,它会被充满细胞并被-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)调用的时间与我提供的完全相同-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section.

那是对的吗?不应该只是可见细胞的数量?

因为在我的情况下我的情况很糟糕:我有很多自定义单元格(50~100个单元格)并且调用-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)每个单元格会减慢部分的打开速度,导致每次执行从nib读取并且正在填充单元格内容图片.我-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)像这样检查内部细胞的可见性:

if ([[self.tableView indexPathsForVisibleRows] containsObject:indexPath])
    NSLog(@"visible %@", indexPath);
Run Code Online (Sandbox Code Playgroud)

并且它表明,在45个细胞中,只有6或7个可见.其他人不在可见区域.但创建细胞仍然执行.这是代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath    {
static NSString *CellIdentifier = @"IVCell";
IVCamera *camera = [server.cameras objectAtIndex:indexPath.row];

IVServerListViewCell *cell = (IVServerListViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"IVServerListCell" owner:self options:nil];
    cell = (IVServerListViewCell*)_tableViewCell;
    self.tableViewCell = nil;

}

[cell textLabel].text = camera.cameraName;
cell.preview = camera.preview;
cell.userData = camera; 
cell.isEnabled = (server.isInactive)?NO:camera.isOnline;

return cell;
}
Run Code Online (Sandbox Code Playgroud)

它还是正确的吗?或者我错过了什么?

jas*_*tjd 6

增加你的

UITableview 的估计行高度。


pee*_*onn 5

好吧,我不知何故处理了我的问题.以下是我的想法和想法,我是如何找到解决方案的.也许它对某人有帮助.

我在打开部分事件期间使用Instruments指示了内存分配和调用堆栈.它告诉我,大部分时间花在从nib文件加载单元格上.

首先,我所做的是减少nib文件的大小,即最小化自定义tableview单元格中使用的视图数量(现在只有2个视图和2个标签,而不是之前的6个视图,2个图像和2个标签).它给了我一些细胞加载的改善.Apple文档建议尽可能少地使用视图,不要使用透明度.所以要注意这些建议.

其次,正如我之前发现的那样,并非所有单元格都是可见的-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *),我决定以某种方式减少从nib文件中加载新单元格的数量.为了达到这个目的,我提出了一个简单的想法:为不可见的行返回空白默认单元格,同时从nib加载自定义单元格以显示可见行.这是一段代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self index:indexPath isInvisibleInTableView:tableView])
        return [self getBlankCellForTableView:tableView];

    // the rest of the method is the same
    ...
}

-(BOOL)index:(NSIndexPath*)indexPath isInvisibleInTableView:(UITableView*)tableView
{
    NSMutableArray *visibleIndexPaths = [self getExtendedVisibleIndexPathsForTableView:tableView];

    return ![visibleIndexPaths containsObject:indexPath];
}

-(UITableViewCell*)getBlankCellForTableView:(UITableView*)tableView
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IVBlankCell"];
    if (!cell)
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"IVBlankCell"] autorelease];

    return cell;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我不是仅仅使用-(NSArray*)indexPathsForVisibleRowstableview方法来检测可见细胞.相反,我已经编写了自己的方法-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView.这是必要的,因为出于某种原因,当使用-(NSArray*)indexPathsForVisibleRows最后一个可见单元格旁边的单元格或第一个可见单元格之前的单元格被创建为空白单元格时,在滚动时看起来像空单元格.为了解决这个问题,在-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView: (UITableView*)tableView我将边界单元添加到可见阵列单元格中:

-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView{
    NSArray *visibleIPs = [tableView indexPathsForVisibleRows];

    if (!visibleIPs || ![visibleIPs count])
        return [NSMutableArray array];

    NSIndexPath *firstVisibleIP = [visibleIPs objectAtIndex:0];
    NSIndexPath *lastVisibleIP = [visibleIPs objectAtIndex:[visibleIPs count]-1];

    NSIndexPath *prevIndex = ([firstVisibleIP row])?[NSIndexPath indexPathForRow:[firstVisibleIP row]-1  inSection:[firstVisibleIP section]]:nil;
    NSIndexPath *nextIndex = [NSIndexPath indexPathForRow:[lastVisibleIP row]+1 inSection:[lastVisibleIP section]];

    NSMutableArray *exVisibleIndexPaths = [NSMutableArray arrayWithArray:[tableView indexPathsForVisibleRows]];

    if (prevIndex)
        [exVisibleIndexPaths addObject:prevIndex];
    [exVisibleIndexPaths addObject:nextIndex];

    return exVisibleIndexPaths;
}
Run Code Online (Sandbox Code Playgroud)

因此,我减少了打开具有大量自定义单元格的部分的时间,这在仪器跟踪和体验应用程序时感觉到了.