问题
Here is my code:
-(IBAction)saveDownloadedImage
{
NSLog(@"Test"); EXECUTED
indicatorView.hidden = NO; NOT EXECUTED
[indicatorView startAnimating]; NOT EXECUTED
[statusLabel setText:@"WHY?"]; NOT EXECUTED
[currentPicture setImage:[imageView image]]; EXECUTED
ImageFileManager *fileManager = [[ImageFileManager alloc] init]; EXECUTED
[fileManager saveImageToDisk:currentPicture]; EXECUTED
indicatorView.hidden = YES;
[statusLabel setText:@"Image saved successfully."]; EXECUTED
saveButton.enabled = NO; EXECUTED
}
The proccess of saving takes about 5 seconds. So it would be normal to see the indicator in the UI. But nothing happens! Any idea?
回答1:
Everything is executed. Your problem is that the saveImageToDisk
call is synchronous and you are calling it from the UI thread. When you are blocking the UI thread, nothing is ever repainted. The indicator is shown but it cannot be drawn to the screen until the IBAction
returns when it will have been hidden again.
You have to call the saving method asynchronously.
Blocking UI thread is never a good idea.
Edit: see the answer for the following question for the correct solution: asynchronous calls to database in ios
Edit2: One of the possible solutions (not tested)
-(IBAction)saveDownloadedImage {
indicatorView.hidden = NO; //Note you can use hidesWhenStopped property for this
[indicatorView startAnimating];
[statusLabel setText:@"BECAUSE..."];
[currentPicture setImage:[imageView image]];
[NSThread detachNewThreadSelector:@selector(save) toTarget:self withObject:nil]
}
- (void)save {
@autoreleasepool {
ImageFileManager *fileManager = [[ImageFileManager alloc] init];
[fileManager saveImageToDisk:currentPicture];
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
}
}
- (void)updateUI {
indicatorView.hidden = YES;
[statusLabel setText:@"Image saved successfully."];
saveButton.enabled = NO;
}
回答2:
Are you sure that
1) indicatorView and statusLabel are not null, and
2) indicatorView and statusLabel are added as subviews to self.view?
回答3:
In My Perception your are starting the Activity Indicator main Thread.
Instead Showing the Indicator on main thread
you should call Indicator on seperate Thread as Below.
-(IBAction)saveDownloadedImage
{
NSLog(@"Test"); EXECUTED
commented below code
//indicatorView.hidden = NO; NOT EXECUTED
// [indicatorView startAnimating]; NOT EXECUTED
//instead of main thread create new Thread as Below
[NSThread detachNewThreadSelector:@selector(showloader) toTarget:self withObject:nil];
[statusLabel setText:@"WHY?"]; NOT EXECUTED
[currentPicture setImage:[imageView image]]; EXECUTED
ImageFileManager *fileManager = [[ImageFileManager alloc] init]; EXECUTED
[fileManager saveImageToDisk:currentPicture]; EXECUTED
[statusLabel setText:@"Image saved successfully."]; EXECUTED
saveButton.enabled = NO;
[indicatorView stopAnimating:YES];
indicatorView.hidden = YES;
}
//Custome method For shoing the Indicator.
-(void)showloader{
//call below method here indicatorView object created already.
[indicatorView startAnimating]
}
It'll definitely work
回答4:
You need to declare your method with a sender like this
-(IBAction)saveDownloadedImage:(id)sender
来源:https://stackoverflow.com/questions/9395361/user-interface-commands-skipped-in-ibaction