我有一个非常简单而烦人的问题。我有两个视图控制器,在第一个我有一个按钮,必须去服务器并做一些工作,我想显示一个包含旋转指示器的警报视图,一旦按下按钮就会显示第二个视图控制器加载时被解雇。
我试过这样的方式:
- (IBAction)logMeInFunction:(id)sender {
UIAlertView *waitAlert = [[UIAlertView alloc] initWithTitle:@"Please Wait...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[waitAlert show];
/* Do Some Api testing and stuff */
[waitAlert dismissWithClickedButtonIndex:0 animated:YES];
[self performSegueWithIdentifier: @"logMe" sender: self];
}
使用这种方式,警报显示在第二个视图控制器中立即显示并解除,而不是在第一个显示中显示,以通知用户某些工作正在完成并在第二个视图中消失。 有什么想法吗?
答案 0 :(得分:1)
您的代码的主要问题是您的服务器调用需要是异步的。您现在正在使用dataWithContentsOfURL,它是同步的并且会阻止您的主线程。
一个简单的选择是在另一个线程中进行该调用。
UIAlertView *waitAlert = [[UIAlertView alloc] initWithTitle:@"Please Wait...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[waitAlert show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *strURL2 = [NSString stringWithFormat:@"MyURL"];
NSData *dataURL2 = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL2]];
NSString *strResult2 = [[NSString alloc] initWithData:dataURL2 encoding:NSUTF8StringEncoding];
NSDictionary *json2 = [strResult2 JSONValue];
NSMutableArray *userExists = [[NSMutableArray alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
[waitAlert dismissWithClickedButtonIndex:0 animated:YES];
[self performSegueWithIdentifier: @"logMe" sender: self];
});
});
答案 1 :(得分:0)
不显示UIAlertview,而是使用标签和指示器显示Custome UIView ... 试试下面的代码...
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0.0,0.0,200.0,200.0)];
customView.layer.cornerRadius = 5.0;
customView.layer.borderColor = [UIColor lightGrayColor].CGColor;
customView.layer.borderWidth = 1.0;
[self.view addSubview:customView];
UILabel* loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(leftMargin, topMargin, 200.0, 100.0)];
[loadingLabel setNumberOfLines:4];
[loadingLabel setTextAlignment:NSTextAlignmentCenter];
[loadingLabel setText:@"Loading..."];
[customView addSubview:loadingLabel];
UIActivityIndicatorView* loadingIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(leftMargin + 75.0, topMargin + 45.0, 50.0, 50.0)];
[loadingIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[customView addSubview:loadingIndicator];
服务器完成后,隐藏/删除自定义视图并加载下一个视图控制器....
答案 2 :(得分:0)
IMO,您需要utilize background thread
。主线程将运行HUD,后台线程将命中服务器并执行操作。
Psuedo代码:
-(void)sendRequestToServer
{
// TODO: Call server to do some function
// Once you are done with server action, you have to come back to MAIN THREAD
[self performSelectorOnMainThread:@selector(hideHUD) withObject:nil waitUntilDone:NO];
}
- (IBAction)logMeInFunction:(id)sender
{
[MBProgresssHUD showHUDAddedTo:self.view animated:YES];
[self performSelectorInBackground:@selector(sendRequestToServer) withObject:nil];
}
-(void)hideHUD
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
注:
请查看克隆中给出的示例,并查看dispatch_async
和dispatch_sync
块。
希望它有所帮助!
答案 3 :(得分:0)
可能性:
1)UIAlertView或带有动画的任何其他视图将需要一些mili第二次在屏幕上显示自己。因此,即使UIAlertView出现在屏幕上,您的服务电话也可能很快就会在此处给出回复。
2)UIAlertView需要一段时间才能在屏幕上显示,因此您的服务器调用可能会使UIAlertview等到Web服务执行完成,因为两者都在主线程上执行。因此,您应该在显示警报视图后使用延迟来调用服务功能,或者您应该使用GCD。