这应该很简单: 当调用didSelectRowAtIndexPath时,我运行一个复杂的方法,它下载URL的内容,解析它,并将结果放在各种属性中。 在模拟器中,在WiFi情况下的设备上,一切都很好。但是,在较慢网络上的设备上,只需要一些时间来处理这一切。 因此,我想在所选行的单元格中显示一个微调器,以便让用户感觉到某些事情正在发生。
我的问题是,在选择行的视图和后续视图之间的动画过渡期间,似乎只显示微调器。
我希望微调器在下载,解析和动画期间显示。
我试过了:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
myCustomCell = (MyCustomCell*)[tableView cellForRowAtIndexPath:indexPath];
[myCustomCell.spinner startAnimating];
return indexPath;
}
和
- (NSIndexPath *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
myCustomCell = (EventCell*)[tableView cellForRowAtIndexPath:indexPath];
[myCustomCell.spinner startAnimating];
[self myVerySlowMethod];
return indexPath;
}
然而,旋转器似乎只显示在两个视图之间。
我在Real Device上测试了这个,我从来没有让微调器显示出来。
这是:
a)因为myVerySlowMethod足够快? b)因为didSelectRowAtIndexPath将首先处理所有内容,然后执行显示部分或 c)在我打扰你之前,我应该学习所有精心编写的编程指南吗?
感谢任何回答。
答案 0 :(得分:1)
问题是在这两种情况下,你的[self myVerySlowMethod](或等效的)都阻塞了主线程,因此ActivityIndicator不会播放。
最好的方法是在后台线程上运行myVerySlowMethod,然后在完成后调用另一个将新视图控制器推送到导航堆栈的方法。
首先,调用方法在后台运行:
[self performSelectorInBackground:(@selector(myVerySlowMethod)) withObject:nil];
这将自动创建一个新的后台线程供您运行。然后,您必须确保在后台方法中执行以下操作:
-(void) myMethod {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// code you want to run in background thread;
[pool drain];
}
这是必要的,因为没有为除主要线程之外的任何线程设置默认自动释放池。
最后,您需要将新视图控制器推送到主线程上的导航堆栈中。如果您有另一种方法,请从后台线程中调用它,如下所示:
[self performSelectorOnMainThread:(@selector(myOtherMethod)) withObject:nil
waitUntilDone:YES];
如果你想在其后做其他事情,可选的第三个参数将为你提供主线程。
希望有所帮助!