User Interface commands skipped in IBAction

雨燕双飞 提交于 2019-12-10 11:27:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!