I'm doing a synchronous web request, and I'd like to show progress, but more importantly, as soon as i tap "Start" it's off to the races ignoring things like turning on the NetworkActivty spinner or changing the labels.
I realize that the progress bars may have to wait until i have time to write the fetches asyncronously, but can I get the program to wait until the labels have changed? Or at least a way to fake it?
On TouchUpInside on a UIButton I have. . .
-(IBAction)startButtonPressed
{ [UIApplication sharedApplication].ne开发者_StackOverflow社区tworkActivityIndicatorVisible = YES;
NSString *lastUpdate = [[self getLastUpdateDate] stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
startButton.enabled = NO;
cancelButton.enabled = NO;
resetSwitch.enabled = NO;
cleanSwitch.enabled = NO;
//check the # of customer updates and update accordingly
statusLabel.text = @"Updating Customers. . .";
//[self performSelector:(@selector(updateProgress:withStatus:)) withObject:0.0f withObject:@"Updating Customers. . . " afterDelay:500];
//[self performSelector:(@selector(updateProgressIndicators)) withObject:nil afterDelay:0];
if (clean) {
[self deleteALL];
}
if ([self customersCount] < 1000 && !reset)
[self addCustomers:lastUpdate];
else
[self addCustomers:nil];
//check the # of product updates and update accordingly, reset does not affect products
statusLabel.text = @"Updating Products. . .";
if ([self productsCount] < 25000 || !clean)
[self addProducts:lastUpdate];
else
[self addProducts:nil];
//check the # of vendor updates and update accordingly, reset does not affect vendors
statusLabel.text = @"Updating Vendors. . . ";
if ([self vendorsCount] < 1000 || !clean || [[self fetchVendor:@"0002"] count] == 0) {
[self addVendors:lastUpdate];
}else{
[self addVendors:nil];
}
statusLabel.text = @"Updating History. . . ";
[self getHistory];
statusLabel.text = @"Updating Custom Pricing. . . ";
if ([self customPricesCount] < 500 && !reset) {
[self addCustomPrices:lastUpdate];
}else{
[self addCustomPrices:nil];
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd-yyyy HH:mm:ss"];
[self setLastUpdateDate:[dateFormatter stringFromDate:[NSDate date]]];
[dateFormatter release];
statusLabel.text = @"Done!";
cancelButton.enabled = YES;
cancelButton.tag = 1;
cancelButton.titleLabel.text = @"Close";
startButton.enabled = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
One possibility you have is scheduling the network request for execution on the main thread. This will allow the UI to get updated before the network request is sent out.
In ordert to do so, you should split your code in two methods:
UI change (activity indicator and so on) up to the synchronous network request;
synchronous network request and response processing (with UI update);
Say that 2. is implemented by a method called offToTheRaces
, you would schedule this method from the first one:
[self performSelector:@selector(offToTheRaces) withObject:nil afterDelay:0];
notice that you are not doing any kind of multithreading this way, nor are you introducing a delay. You simply schedule the method to be executed once the main loop is executed again and this will give tue UI a chance to get updated.
精彩评论