按下按钮时显示活动指示器动画

发布于 2024-12-02 23:49:29 字数 1580 浏览 1 评论 0原文

我有一个名为“同步”的按钮。当点击/按下时,它会将数据发送到网络服务器并由服务器检索答案(这需要一段时间并冻结 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 上工作

I have a button called "Sync". When tapped / pressed it sends data to a webserver and retrieves the answer by the server (what takes a while and freezes the gui / button) so how do I add a "Please wait" and activity indicator until the data / answer from the server arrives and the text / indicator is deleted and replaced by the answer from the server?

This code freezes my app:

- (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];
}

i am working on a Mac Mini with iOS 10.6.7

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

戈亓 2024-12-09 23:49:29

在 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 的类参考。上述两个块均取自该块。

http://developer.apple.com/library /mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

Adding an activity indicator in UIAleartView will help.
Checkout this...

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];

EDIT:
Probably the reason why your application is getting blocked is this method

sendSynchronousRequest:(NSURLRequest *)request

Following is the description of the method.

A synchronous load is built on top of the asynchronous loading code made available by the class. The calling thread is blocked while the asynchronous loading system performs the URL load on a thread spawned specifically for this load request. No special threading or run loop configuration is necessary in the calling thread in order to perform a synchronous load.

If you don't want you application to block then call this from other thread. Read following too.

Important: Because this call can potentially take several minutes to fail (particularly when using a cellular network in iOS), you should never call this function from the main thread of a GUI application.

Please refer to Class reference of NSURLConnection. Both of above blocks are taken from that.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

樱&纷飞 2024-12-09 23:49:29

您的同步请求会阻塞 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];
}

Your synchronous request blocks the UI thread and that's why activity indicator will not start. You should use NSURLConnection asynchronously for multiple reasons, and that's one of them.

Instead of:

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

Do:

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
[conn release];

Then make returnData instance variable and implement NSURLConnectionDeletgate methods:

- (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];
}
苏璃陌 2024-12-09 23:49:29

对于同步使用:(形式不好,但可行的解决方案)

//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];
}

For synchroneous use: (bad form, but working solution)

//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];
}
浅暮の光 2024-12-09 23:49:29
//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];
//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];
拍不死你 2024-12-09 23:49:29

创建:

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];

最终完成后,从视图中删除微调器并释放。

Create:

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

Start:

[spinner startAnimating]; 

Stop:

 [spinner stopAnimating];

When you're finally done, remove the spinner from the view and release.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文