Показывать анимацию индикатора активности при нажатии кнопки
У меня есть кнопка "Синхронизация". При нажатии / нажатии он отправляет данные на веб-сервер и получает ответ от сервера (что занимает некоторое время и останавливает графический интерфейс пользователя / кнопку), так как мне добавить индикатор "Пожалуйста, подождите" и индикатор активности, пока данные / ответ не поступят с сервера приходит и текст / индикатор удаляется и заменяется ответом с сервера?
Этот код останавливает мое приложение:
- (IBAction) syncButtonTapped
{
[syncButton setEnabled:NO];
//resultText.text= @"Bitte warten ...";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: @"deck.txt"];
NSString *post = [NSString stringWithContentsOfFile:docFile encoding:NSUTF8StringEncoding error:nil];
NSString *post2 = [post stringByReplacingOccurrencesOfString:@"\n" withString:@","];
NSString *post3 = [post2 stringByReplacingOccurrencesOfString:@"\r" withString:@""];
NSString *post4 = [NSString stringWithFormat:@"{\"results\":[%@]}",post3];
NSString *urlString = [NSString stringWithFormat:@"http://storecheck.cortona.de/fetchresults.php?results=%@",[post4 stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"GET"];
NSString *data4 = @"";
[data4 writeToFile: docFile atomically: NO encoding: NSUTF8StringEncoding error:nil];
//send request & get response
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
}
я работаю на Mac Mini с iOS 10.6.7
5 ответов
Ваш синхронный запрос блокирует поток пользовательского интерфейса, поэтому индикатор активности не запускается. Вы должны использовать NSURLConnection асинхронно по нескольким причинам, и это одна из них.
Вместо:
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
Делать:
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
[conn release];
Затем создайте переменную экземпляра returnData и реализуйте методы NSURLConnectionDeletgate:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
returnData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[returnData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
// do whatever you need with your string and stop activity indicator
[returnData release];
}
Добавление индикатора активности в UIAleartView поможет. Оформить заказ...
UIAlertView *waitAlert = [[[UIAlertView alloc] initWithTitle:@"Please Wait...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
[waitAlert show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
// Adjust the indicator so it is up a few pixels from the bottom of the alert
indicator.center = CGPointMake(waitAlert.bounds.size.width / 2, waitAlert.bounds.size.height - 50);
[indicator startAnimating];
[waitAlert addSubview:indicator];
[indicator release];
РЕДАКТИРОВАТЬ: Вероятно, причина, по которой ваше приложение блокируется является этот метод
sendSynchronousRequest:(NSURLRequest *)request
Ниже приведено описание метода.
Синхронная загрузка создается поверх кода асинхронной загрузки, предоставляемого классом. Вызывающий поток блокируется, пока асинхронная система загрузки выполняет загрузку URL-адреса для потока, созданного специально для этого запроса загрузки. Для выполнения синхронной загрузки в вызывающем потоке не требуется специальной настройки потоков или цикла выполнения.
Если вы не хотите, чтобы приложение блокировалось, вызовите это из другого потока. Читайте следующее тоже.
Важное замечание: Поскольку этот вызов потенциально может потерпеть неудачу в течение нескольких минут (особенно при использовании сотовой сети в iOS), вам никогда не следует вызывать эту функцию из основного потока приложения с графическим интерфейсом.
Пожалуйста, обратитесь к Ссылка класса NSURLConnection. Оба вышеперечисленных блока взяты из этого.
Для синхронного использования: (плохая форма, но рабочее решение)
//Right before the request is made
UIActivityIndicatorView* indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indicatorView setFrame:CGRectMake(0, 0, 16, 16)];
[indicatorView setHidesWhenStopped:YES];
[indicatorView startAnimating];
[self.view addSubview:indicatorView];
// Create your request (synchronously or asynchronously)
[self performSelector:@selector(myDoRequest:) withObject:self afterDelay:0.1];
//this gives time for the runloop to complete at least one screen draw..
...
-(void)myDoRequest:(id)sender {
// Create your request (synchronously or asynchronously)
...
// When request is done
[indicatorView stopAnimating];
[indicatorView release];
}
Создайте:
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[spinner setCenter:CGPointMake(kScreenWidth/2.0, kScreenHeight/2.0)]; // I do this because I'm in landscape mode
[self.view addSubview:spinner]; // spinner is not visible until started
Начните:
[spinner startAnimating];
Стоп:
[spinner stopAnimating];
Когда вы, наконец, закончите, уберите спиннер с поля зрения и отпустите.
//Right before the request is made
UIActivityIndicatorView* indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indicatorView setFrame:CGRectMake(0, 0, 16, 16)];
[indicatorView setHidesWhenStopped:YES];
[indicatorView startAnimating];
[self.view addSubview:indicatorView];
// Create your request (synchronously or asynchronously)
...
// When request is done
[indicatorView stopAnimating];
[indicatorView release];