我试图在viewDidLoad中加载数据时显示一个指示器视图,但是在显示指示符之前加载开始,我猜这是因为直到之后才加载视图。我一直在读这个,但是无法让它发挥作用。
我想要的是在将文件加载到数据库期间显示活动指示器。
我一直在做测试,所以代码结构可能看起来有点奇怪。
有人可以请给我一个提示或链接,如何解决这个问题,以便在/如果数据从.txt文件加载到数据库中时显示活动指示符?
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @" ";
loadActivityIndicator.hidden = TRUE; // Hide UIActivityIndicationView at start
[self loadDataIfNeeded];
}
-(void)loadDataIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
myFileArray = [[NSMutableArray alloc]init];
//======SET THE FILE INPUT NAME======//
qFileTxtName = @"110615";
[myFileArray addObject:qFileTxtName];
//===================================//
// CHECK IF THE FILE EXISTS
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"checkQuestionFile.plist"];
if([fileManager fileExistsAtPath:path]) {
NSArray *readKeyFileName = [[NSArray alloc] initWithContentsOfFile:path];
if ([[readKeyFileName objectAtIndex:0] isEqualToString:qFileTxtName]) {
//==== THERE IS NO UPDATED QUESTION .txt FILE ====//
}
else {
//==== THERE IS AN UPDATED QUESTION .txt FILE ====//
// SET UP UIActivityIndicator view to show that work is ongoing
loadActivityIndicator.hidden = FALSE;
[loadActivityIndicator startAnimating];
//==== SET UP PATH FOR ALL FILES====//
NSString *aString = [[NSString alloc]init];
aString = [@"questions_famquiz_hard_" stringByAppendingString:qFileTxtName];
NSString *path1 = [[NSBundle mainBundle] pathForResource:aString ofType:@"txt"];
aString = [@"questions_famquiz_medium_" stringByAppendingString:qFileTxtName];
NSString *path2 = [[NSBundle mainBundle] pathForResource:aString ofType:@"txt"];
aString = [@"questions_famquiz_easy_" stringByAppendingString:qFileTxtName];
NSString *path3 = [[NSBundle mainBundle] pathForResource:aString ofType:@"txt"];
AccessQuestionsDB *accessQuestionDataFunction = [AccessQuestionsDB new];
idCounter = [accessQuestionDataFunction populateTheDatabase: path1 theID:0 firstTime: YES];
idCounter = [accessQuestionDataFunction populateTheDatabase: path2 theID:idCounter firstTime: NO];
idCounter = [accessQuestionDataFunction populateTheDatabase: path3 theID:idCounter firstTime: NO];
//==UPDATE THE PLIST==//
[myFileArray writeToFile:path atomically: TRUE];
// Stop UIActivityIndicator as activity is over
loadActivityIndicator.hidden = TRUE;
[loadActivityIndicator stopAnimating];
}
} else {
//== If file not found write a new file ==//
[myFileArray addObject:qFileTxtName];
[myFileArray writeToFile:path atomically: TRUE];
}
}
问题已解决
我替换了电话
[self loadDataIfNeeded];
用;
[NSThread detachNewThreadSelector:@selector(loadDataIfNeeded)toTarget:self withObject:nil];
根据约拿的建议实现多线程: - )
答案 0 :(得分:1)
您正在主线程中同步加载数据。这意味着主线程,即负责绘制UI的主线程,正在忙于加载您的数据,并且在您的loadDataIfNeeded
方法完成之后将无法更新您的视图(此时您不希望显示您的活动指示器无论如何都可见。)
在主线程上显示活动指示符,然后允许主线程的运行循环继续,而是在辅助线程上异步执行昂贵的操作(如加载数据或执行网络请求)。
查看NSThread
,NSObject
的{{1}}和-performSelectorInBackground:withObject:
,了解从主线程执行任务的不同选项。
答案 1 :(得分:0)
Matt Drance撰写的“IOS Recipes”一书讲述了如何做到最好。您可以在http://media.pragprog.com/titles/cdirec/activity.pdf
的书中免费摘录此食谱 的图书页面上找到该食谱的源代码答案 2 :(得分:0)
在viewDidLoad中添加
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.frame = CGRectMake(0, 0, 44, 44);
activityView.center = self.view.center;
activityView.tag = 99;
[activityView startAnimating];
[self.view addSubview: activityView];
[activityView release];
然后在加载方法完成加载后,只需从超级视图中删除活动指示器。
在加载add
后的loadDataIfNeeded中 [[self.view viewWithTag:99] removeFromSuperview];