当我在asynchronous重载数据期间滚动时,为什么我的UITableView失去stream动性?
这是我的问题…我正在对我正在使用的服务进行asynchronous调用,它将search结果返回给我。 完成后,重新载入我的表,并完成asynchronous。 问题是,当我尝试在asynchronous调用完成之前在我的表视图上滚动时,该表失去了所有滚动视图所具有的stream畅感。 我的意思是,当你放开卷轴而不是继续前进,慢慢停下来的时候,只要你放开,它就会停下来。 唯一的方法来恢复stream体的感觉是滚动一直到UITableView的顶部或底部和一点点过去,那就没事了。
这是我的asynchronous调用代码:
__block NSMutableArray *appendMoreObjects = [[NSMutableArray alloc] init]; dispatch_async( dispatch_get_main_queue(), ^{ self.activity.hidden = NO; appendMoreObjects = [service search:self.query from:((moreCount * 8)) until:((moreCount * 8) + 8)]; if( appendMoreObjects == nil ) { //alert view } else { [self.allSearchResults addObjectsFromArray:appendMoreObjects]; [self updateSearchArray]; self.moreCount += 1; } self.activity.hidden = YES; });
另外,请记住,我正在使用自定义的UITableViewCell。 如果需要其他信息,请申请,我会看看我能做些什么。 先谢谢你。
EDIT1:[self updateSearchArray]包含[tableView reloadData]
编辑2:我在运行4.3.1(8G4)的iPod Touch上testing
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { customCell * cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:@"cell"]; if( cell == nil ) { cell = [[[customCell alloc] initWithFrame:CGRectZero] autorelease]; } if( indexPath.row == [self.searchResults count] && [self.searchResults count] > 0) { UITableViewCell *moreCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease]; moreCell.textLabel.text = @"More"; moreCell.textLabel.textAlignment = UITextAlignmentCenter; return moreCell; } if( indexPath.row < [self.searchResults count] ) { [cell formatAndInsertData:[self.searchResults objectAtIndex:indexPath.row]]; } return cell; }
解:
我最终做的是locking桌子和所有的用户界面元素,直到调用完成。 也许不是最好的解决scheme,但它的工作就不那么简单了。
调用[tableView reloadData]
将重新加载你的ENTIRE表,这就是你看到波涛汹涌的UITableView的原因。 它强制所有可见的单元格刷新,因此,当您滚动时,可见单元格会刷新并重新绘制自己。 您需要重新评估更新UITableView的策略,因为您有数据来避免这种情况。 您应该更新单个单元格,这些单元格可能包含与您的更新相关的数据。
为此,您将需要使用以下方法:
– insertRowsAtIndexPaths:withRowAnimation: – deleteRowsAtIndexPaths:withRowAnimation: – reloadRowsAtIndexPaths:withRowAnimation:
这些组合将允许您在接收数据时更新您的表(添加/删除行),而不是强制刷新整个表。
确保你只是在主线程上重新加载表数据。 最好,我使用nsinvocation而不是GCD 🙂
我想看看自定义单元格,以完全回答你的问题。
此外,您的表格控制器cellForRowAtIndexPath:段,看看你是如何重用您的单元格。
最后但并非最不重要的是:您正在testing哪种types的设备? (types和世代)
编辑:
这部分 :
if( indexPath.row == [self.searchResults count] && [self.searchResults count] > 0) { UITableViewCell *moreCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease]; moreCell.textLabel.text = @"More"; moreCell.textLabel.textAlignment = UITextAlignmentCenter; return moreCell; }
看起来彻头彻尾的有毒…现在没有时间来testing它,但请不要在单元格内添加单元格… tablecontroller将不仅困惑,但阻止了太多的内存。
只使用cellForRowAtIndexPath:简单的事情,如填写标题,描述和图像。
在桌面视图控制器上执行重新加载逻辑,但在某处更安全。 cellForRowAtIndexPath将在每次出现单元格时加载,即使它正好在视线内。