我有一个名为“同步”的按钮。当点击/按下它时,它会将数据发送到网络服务器并由服务器检索答案(需要一段时间并冻结gui /按钮),那么如何添加“请等待”和活动指示器,直到服务器的数据/答案为止到达并删除文本/指示符并替换为服务器的答案?
此代码冻结了我的应用:
- (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];
}
我正在使用iOS 10.6.7的Mac Mini
答案 0 :(得分:5)
在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中使用移动网络时),因此不应该从GUI应用程序的主线程中调用此函数。
请参阅NSURLConnection的课程参考。以上两个块都是从中获取的。
答案 1 :(得分:4)
您的同步请求会阻止UI线程,这就是活动指示器无法启动的原因。您应该出于多种原因异步使用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];
}
答案 2 :(得分:4)
同步使用:(形式不好,但工作解决方案)
//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];
}
答案 3 :(得分:1)
//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];
答案 4 :(得分:1)
创建强>
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];
当你最终完成后,从视图中删除微调器并释放。