My cocoa app needs to fetch data from network and then shows content in the table view. So I add a spinning style of NSProgressIndicator
to animate when the data is downloading. After that the animation of NSProgressIndicator
stops and reloads the NSTableView
. The strange thing is after the table view reloading, the content shown is not updated. Then If you scroll the table view, the content starts to show,just like:
(the small rectangle above is the frame for the
NSProgressIndicator
)
Below is my code:
- (void)loadOperationData
{
dispatch_async(dispatch_get_main_queue(), ^{
[self _showIndicator];
});
[NSThread detachNewThreadSelector:@selector(getOperationLogProcess) toTarget:self withObject:nil];
}
- (void)_showIndicator
{
if (indicator == nil)
{
indicator = [[NSProgressIndicator alloc] init];
[indicator setStyle:NSProgressIndicatorSpinningStyle];
[indicator setUsesThreadedAnimation:NO];// I tried to comment this, but no use
int width = 30;
CGRect rect = CGRectMake(0, 0, width, width);
NSRect selfRect = [_coverView frame];
rect.origin.x = selfRect.size.width/2 - width/2;
rect.origin.y = selfRect.size.height/2 - width/2;
indicator.frame = rect;
[_coverView addSubview:indicator];
}
[indicator setHidden:NO];
[indicator startAnimation:self];
}
-(void)getOperationLogProcess{
NSDictionary *tempResutDic = [WebServiceManager getOperationLog];//using synchronous ASIHttpRequest to download data
if ([[tempResutDic objectForKey:@"resultCode"] intValue]==100) {
self.operationLogArray = [tempResutDic objectForKey:@"items"];
[self performSelectorOnMainThread:@selector(reloadTableview) withObject:nil waitUntilDone:YES];//refresh UI in main thread
}
}
-(void)reloadTableview
{
[indicator stopAnimation:self];
[indicator setHidden:YES];
[operationlogTable setEnabled:YES];
if ([_coverView isHidden])
{
return;
}
self.lastUpdateDate = [NSDate date];
[operationlogTable reloadData];
}
The -(void)loadOperationData
is called by the mouse click event. And The reason why I put the -(void)_showIndicator
in a dispatch block is that the indicator can't be shown. I tried a lot and finally chose it.
I guess the problem ties closely to the way of showing indicator because If I commented the code about the indicator, the problem dismissed.
I really need the indicator to let user know they are waiting.So Please help me how to correctly use NSProgressIndicator.
Thanks!
It caused by the multithread.
In- (void)loadOperationData
I use main block to show progress indicator and create a thread to fetch data in background. The block is run asynchronously and sometimes is after the -(void)reloadTableview
.
Finally, I keep - (void)loadOperationData
is called in main thread and put the - (void)_showIndicator
out of the block. Then it is fixed.