我有一个UITableViewController,它是RootViewController。它的XIB只有一个表格视图。我通过IB添加了一个UIActivityIndicator并创建了一个IBOutlet。我已经以编程方式向RootViewController添加了一个带有删除按钮的工具栏。当用户单击工具栏的删除按钮时,我想以屏幕为中心显示指示符。下面的方法从数据库中删除数据,这种情况发生得非常快。我想让用户知道正在发生的事情。如果我在没有sleep()的情况下运行下面的代码,它会快速发生并且我看不到指示器。但有些人出于某种原因,我还是没有看到这个指标。我猜睡眠()块重新粉刷?如果我拿出睡眠()和最后两行,我会看到指示器但当然它永远不会消失。它也显示在窗口的左上角。
如何让下面的代码工作,使指示器至少显示1/2 - 1秒?
如何将指示器对准窗口中间?
[self.navigationController.view addSubview:activityIndicator];
[activityIndicator startAnimating];
[activityIndicator setNeedsDisplay];
//do something which might happen really fast
sleep(1); //create illusion
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
答案 0 :(得分:6)
在您处理完事件并返回到运行循环之前,微调器不会开始旋转。解决这个问题的方法是让运行循环为你完成任务。
这是我的意思的一个例子:
- (IBAction)deleteAction:(id)sender {
[self.navigationController.view addSubview:activityIndicator];
[activityIndicator startAnimating];
// Spinner won't start spinning until we finish processing this event, so
// we're just going to schedule the rest of what we need to do.
// doDelete: will run when the main thread gets its next event.
[self performSelectorOnMainThread:@selector(doDelete:)
withObject:record
waitUntilDone:NO];
// removeSpinner: will run in at least one second, but will wait if
// another event (like the doDelete: one) is in the middle of running.
[self performSelector:@selector(removeSpinner:)
withObject:activityIndicator
afterDelay:1.0];
}
- (void)doDelete:(id)record {
[record delete]; // or whatever it is you need to do
}
- (void)removeSpinner:(UIActivityIndicator*)activityIndicator {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
}
注意:此代码中没有任何内容可以保证在“休眠”期间阻止其处理其他触摸,因此请确保以某种方式锁定其他事件。
答案 1 :(得分:1)
正如Adam所提到的,除非工作(在本例中为Delete操作)在后台线程中完成,否则微调器不会显示。这是我根据布伦特的初始代码开始工作的代码。我修改它来调用我在后台线程中完成工作的函数,然后在完成后使用主线程删除微调器。
- (void)removeSpinner:(id)record {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Thank You" message:@"Thanks for your feedback!"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
// return to feedings tab
tabBarController.selectedIndex = 0;
}
- (void)doFeedback:(id)record {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int j;
for (int i = 0; i < 1000000000; i++) {
j = j + i;
}
[self performSelectorOnMainThread:@selector(removeSpinner:) withObject:nil waitUntilDone:NO];
[pool release];
}
- (IBAction)handleSend {
[self.view addSubview:activityIndicator];
[activityIndicator startAnimating];
// Spinner won't start spinning until we finish processing this event, so
// we're just going to schedule the rest of what we need to do.
// doFeedback: will run when the main thread gets its next event.
[self performSelectorInBackground:@selector(doFeedback:) withObject:nil];
}
答案 2 :(得分:0)
问题在于,当你正在做你的事情时,主运行循环没有运行。为了显示活动指示器,需要运行主运行循环,以便更新其动画。为了获得预期的行为,您需要在一个单独的线程中异步执行数据库操作。
答案 3 :(得分:0)
[self.navigationController.view addSubview:activityIndicator]; [activityIndicator startAnimating];
[self performSelector:@selector(removeSpinner :) withObject:activityIndicator afterDelay:5.0];