when Navigate the another page Need to add activity indicator - ios

#import "LoginVC.h"
#import "HOMEVC.h"
#import "DashboardVC.h"
#interface LoginVC ()
#end
#implementation LoginVC
UIActivityIndicatorView *spinner ;
-(IBAction)login:(id)sender{
NSString *userUpdate =[NSString stringWithFormat:#"%#",[Usernamefileld text]];
NSString *userUpdate1 =[NSString stringWithFormat:#"%#",[PasswordField text]];
NSString *baseURL = [NSString stringWithFormat:#"http://192.168.1.200:8094/YazakiService.svc/LOGIN/%#/%#",userUpdate,userUpdate1];
NSURL *url = [NSURL URLWithString:[baseURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error;
NSData *responseData =[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSMutableArray *serviceResponse=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"got response==%#", serviceResponse);
NSDictionary *template=[serviceResponse objectAtIndex:0];
NSString *test=[template objectForKey:#"ValidState"];
// NSString *test1=[template objectForKey:#"Userid"];
NSString *helloString = #"1";
// //
// NSString *helloString1 =#"LFY430";
if ([test isEqual:helloString]) {
[NSThread detachNewThreadSelector:#selector(threadStartAnimating:) toTarget:self withObject:nil];
[self moveToView];
// UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Login Successfully" message:#"Correct Uername/Password" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
else{
UIAlertView *alert2=[[UIAlertView alloc]initWithTitle:#"Login Failed" message:#"Incorrect Uername/Password" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert2 show];
[self alertView1:alert2 didDismissWithButtonIndex:alert2];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(150, 225, 20, 30)];
[spinner setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
spinner.color = [UIColor blackColor];
[self.view addSubview:spinner];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)moveToView{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DashboardVC *initView = (DashboardVC*)[storyboard instantiateViewControllerWithIdentifier:#"Dashboardvc"];
[initView setModalPresentationStyle:UIModalPresentationFullScreen];
[spinner stopAnimating];
[self presentViewController:initView animated:NO completion:nil];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self moveToView];
}
- (void) alertView1:(UIAlertView *)alertView1 didDismissWithButtonIndex:(NSInteger)buttonIndex
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginVC *initView = (LoginVC*)[storyboard instantiateViewControllerWithIdentifier:#"loginvc"];
[initView setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:initView animated:NO completion:nil];
}
-(void)threadStartAnimating:(id)data
{
[spinner startAnimating];
}
#end
here by i initialse the indicator and start and stop the spinner but its not woking for me...
any one help me to solve the issues how to add the activity indicator when navigation the another view
Thanks in Advance

[self.view addSubview:spinner];
At this line you add the activity indicator to the current ViewController view.
However once you navigate to other view
DashboardVC *initView = (DashboardVC*)[storyboard instantiateViewControllerWithIdentifier:#"Dashboardvc"];
[self presentViewController:initView animated:NO completion:nil];
the current view changes to the new ViewController's view.
The activity indicator isnt present in that view and therefore you wont see your activity indicator there.
To solve, you should again add activity indicator in the second ViewController's viewDidLoad method
In Dashboard VC
- (void)viewDidLoad {
[super viewDidLoad];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(150, 225, 20, 30)];
[spinner setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
spinner.color = [UIColor blackColor];
[self.view addSubview:spinner];
}
A better solution would be to use third party progress huds which make
the loading indicator part absolutely easy like MBProgressHUD

You should add activityindicator on navigation controller so, it is remains on front when you navigate.
you should use MBProgressHud the great third party library.
Just put class in your project and import .h file in your class when you want to show activity indicator and then add HUD (activity indicator) like,
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
// in your case show hud on `self.navigationController.view`
// use main thread to show if required
and hide like,
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do something...
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
});
Hope this will help :)

When you stop UIActivityIndicatorView then also hide it.
[spinner setHidesWhenStopped:YES];
EDIT:
If you are not sure about NSThread then just do like this.
if ([test isEqual:helloString]) {
//[NSThread detachNewThreadSelector:#selector(threadStartAnimating:) toTarget:self withObject:nil];
[spinner startAnimating];
[self moveToView];
}
And when you want to stop it ten
[spinner stopAnimating];
[spinner setHidesWhenStopped:YES];

instead of using indicator , use svprogresshud.Check this link https://github.com/SVProgressHUD/SVProgressHUD.
if you want animated progressbar check this link https://github.com/cemolcay/GiFHUD

Related

Initialize UITableview with Contents from XML but can't show progress with UIAlertview

I am writing an app, which is getting data from the net using XML. It is a master-detail-app which is fetching data for the master-table and after selecting one item from the master-Table it fills the data for the detailview(s) using another network-access.
I would like to present an alert in order to show the user that the app is busy accessing the net or busy calculating. So I would present the view from the UIAlertController before the calculation / network access starts and dismiss the view when the activity has completed
Problem is: I don't know where to put this call to show / dismiss the UIAlertcontroller view.
Putting the activity code into ViewWillAppear shows and dismisses the alertview BEFORE the network-access... Putting everything into ViewDidLoad seems not the way to go.
- (void) viewWillAppear:(BOOL)animated
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Working"
message:#"Working on it"
preferredStyle:UIAlertControllerStyleAlert];
self.objects = [[NSMutableArray alloc] init];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Accounts"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
NSURL *url;
if ([self getSession])
{
NSMutableString *URLstring = [NSMutableString stringWithString:#"https://XXXXXXXXXXXXXXX.xml?session="];
[self presentViewController:alert animated:YES completion:nil];
[URLstring appendString:[[DataStore getData]SessionString]];
url = [NSURL URLWithString:URLstring];
self.myXXXXXXParserAlleKontenXMLDelegate = [[KontenParserDelegate alloc] init];
self.xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
self.xmlParser.delegate = self.myfxbookParserAlleKontenXMLDelegate;
if ([self.xmlParser parse])
{
[self.objects removeAllObjects];
for(int i=0; i< [self.XXXXXXXXXrAlleKontenXMLDelegate.allAccounts count];i++)
{
[self.objects addObject : [self.myfxbookParserAlleKontenXMLDelegate.allAccounts objectAtIndex:i]];
}
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey: #"name" ascending: YES];
[self.objects sortUsingDescriptors:#[sort]];
[self.tableView reloadData];
[self dismissViewControllerAnimated:YES completion:nil];
// Do any additional setup after loading the view, typically from a nib.
}
}
}
Added After some discussions I added some new framework "SVProgressHUD" and entered the following code into "ViewWillAppear" where [self parserstuff] contains all the XML parsing..
[SVProgressHUD show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self parserstuff];
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
});
});
This leaves me with a HUD-Display showing up while parsing XML but the resulting Tableview does not show data but is empty... After switching to DISPATCH_SYNC it works.
Solution would be
1) Put code in ViewDidLoad
2) encapsulate Code between "SVProgressHUD show" and "dismiss" with dispatch_async
as in
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD show];
[self parserstuff];
[self fillComparatorParameters:nil];
[self.tableView reloadData];
[SVProgressHUD dismiss];
// }];
});

Console warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress

"Warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress!"
I'm trying to have my app go to a loading screen upon selecting a picture to upload. This works by, upon selecting a picture, removing the UIImagePickerController scene, adding the Loading scene, and once the upload is complete, removing the Loading scene.
-(void)uploadMessage{
[self dismissViewControllerAnimated:NO completion:nil];
LoadingViewController *loadView = [[LoadingViewController alloc]initWithNibName:#"LoadView" bundle:nil];
[self presentViewController:loadView animated:NO completion:^{
NSData *fileData;
NSString *fileName;
NSLog(#"Image");
fileData = UIImagePNGRepresentation(self.image);
fileName = #"image.png";
PFFile *file = [PFFile fileWithName:fileName data:fileData];
[self.game setObject:file forKey:#"picture"];
[self.game saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if(succeeded){
[self removeAndChangeButtons];
[self dismissViewControllerAnimated:NO completion:nil];
}
}];
}];
}
You can add a function using MBProgressHUD.
- (void) showMessage:(NSString*)message withTitle:(NSString*)title onView:(UIView*)view removeAfter:(NSTimeInterval)delay{
dispatch_async(dispatch_get_main_queue(), ^{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
// Configure for text only and offset down
hud.mode = MBProgressHUDModeText;
hud.labelText = title;
hud.detailsLabelText = message;
hud.margin = 10.f;
hud.yOffset = 0.0f;
hud.removeFromSuperViewOnHide = YES;
[hud hide:YES afterDelay:delay];
});
}
Then in your code when you start the background task, call showMessage and then the upload is done, remove it.
You are dismissing the ViewController twice in your method if it is successful. Obviously, this can't be done. I don't know what exactly what you're trying to achieve, but I think removing the first [self dismissViewControllerAnimated:NO completion:nil] would do the trick.

MBProgressHUD indicator does not hide

i am able to show HUD indicator in viewDidLoad successfully but not able hide it in webViewDidFinishLoad method when webview is completely loaded. Please help.
i am using below code::
in .h file
MBProgressHUD *HUD;
in viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *query = [[NSString alloc] initWithFormat:#"http://localhost/index.php?uid=%#", [[UIDevice currentDevice] uniqueIdentifier]];
NSURL *url = [[NSURL alloc] initWithString:query];
NSString *response = [[NSString alloc] initWithContentsOfURL:url];
if(response)
{
[webView loadRequest:[NSURLRequest requestWithURL:url]];
}
else
{
//NSLog(#"err %#",response);
}
HUD = [[MBProgressHUD showHUDAddedTo:self.view animated:YES] retain];
HUD.delegate = self;
HUD.labelText = #"loading";
}
and in webViewDidFinishLoad
- (void)webViewDidFinishLoad:(UIWebView *)web
{
[HUD hide:TRUE]; //it does not work for me :(
}
i have fixed the error, i moved the code from viewDidLoad to webViewDidStartLoad and everything is working fine this time :)
- (void)webViewDidStartLoad:(UIWebView *)web
{
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = #"loading";
}
- (void)webViewDidFinishLoad:(UIWebView *)web
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
try with this one
[HUD hide:YES];
if(HUD!=nil && [HUD retainCount]>0)
{
[HUD removeFromSuperview];
[HUD release];
HUD=nil;
}
You should not call MBProgressHUD from viewDidLoad, try calling it from viewDidAppear and everything should work well.
Try removing it using this class method:
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated
.
- (void)webViewDidFinishLoad:(UIWebView *)web
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
If you use this method then you should think about rewriting your viewDidLoad this way:
- (void)viewDidLoad
{
[super viewDidLoad];
//...
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = #"loading";
}

DismissModalView Not Working

I've been pulling my hair out a bit over this. I'm creating a very simple app, it simply downloads an rss feed and displays it in a UITableview, which is inside a UINavigationController. Whilst it's downloading the feed I'm presenting a Modal View.
In my modal view I'm displaying a UIImageView and a UIActivityIndicatorView that is set to spin. I'm using ASIHTTRequest to asynchronously grab the feed and then using the either the completion block to get the response string and stop the spinner or the failure block to get the NSError and display a alert View. This all works perfectly.
I've then created a protocol to dismiss the modal view from the tableview which is called inside the completion block. But the modal view is never dismissed! I've tried pushing it into the navigation controller but exactly the same problem occurs. I even have tried setting the modal view delegate to nil but still no luck.
I've checked it without blocks using the ASIHTTPRequest delegate methods and it's the same, and if I don't present the modal view the table view is displayed normally.
Any Ideas? I've skipped out all the tableview delegate and datasource methods as well as the dealloc and any unused functions.
#interface MainTableViewController ()
-(void)loadModalView;
#end
#implementation MainTableViewController
#synthesize tableView;
#synthesize modalView;
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
[super loadView];
tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
[self loadModalView];
}
-(void)loadModalView
{
modalView = [[ModalViewController alloc]init];
modalView.delegate = self;
[self presentModalViewController:modalView animated:NO];
}
//Modal View Delegate
-(void)downloadComplete
{
modalView.delegate = nil;
[self dismissModalViewControllerAnimated:NO];
}
#end
#interface ModalViewController ()
- (void)loadView
{
[super loadView];
backgroundImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:backgroundImage];
spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(160, 240, spinner.bounds.size.width, spinner.bounds.size.height);
spinner.hidesWhenStopped = YES;
[self.view addSubview:spinner];
[spinner startAnimating];
NSString* urlString = FEED_URL;
NSURL* url = [NSURL URLWithString:urlString];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
[spinner stopAnimating];
[delegate downloadComplete];
// Use when fetching binary data
}];
[request setFailedBlock:^{
NSError *error = [request error];
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.description delegate:self cancelButtonTitle:#"Continute" otherButtonTitles: nil];
[alert show];
[alert release];
}];
[request startAsynchronous];
}
Matt
In my understanding.. you solution is quite complicated..
wouldn't it be better if the class MainTableViewController is the
one who downloads the Feeds.. for the ModalView it will just act as an ActivityIndicator and dismiss after downloading..
so inside your MainTableViewController loadview:
- (void)loadView
{
NSString* urlString = FEED_URL;
NSURL* url = [NSURL URLWithString:urlString];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request startAsynchronous];
//after starting the request show immediately the modalview
modalView = [[ModalViewController alloc]init];
[self presentModalViewController:modalView animated:NO];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
//then when it is complete dissmiss the modal
[modalView dismissModalViewControllerAnimated:NO];
// Use when fetching binary data
}];
[request setFailedBlock:^{
NSError *error = [request error];
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.description delegate:self cancelButtonTitle:#"Continute" otherButtonTitles: nil];
[alert show];
[alert release];
}];
}
i didnt use blocks in my projects, but i think it will work the same..
also I use a plain UIActivityIndicatorView (large) as subviews not modalViews.. sadly i cant test the code here now.. but i can check it later though
The only way I solved this error was to synchronously download the data and push and pop the download view onto the navigation stack. Not ideal but it works.

ipad-NSThread-Error

For Check Valid Login,
I Fetch Data From Webservice And To Show Progress ,
I Display UIIndicatorView Inside UIAlertView
Problem Is :
During Progress When Press Home Button Of IPad Device Then My Application Is Close,, And Second Time When I Try To Start App Then (Black Screen Is Display) Apps Is Not Start.
How I Can Solve this problem?
My Code Is:
-(NSMutableString*) getLoginMessage:(NSString*) UserName : (NSString *) Password : (NSString *) url
{
[NSThread detachNewThreadSelector:#selector(showAlertMethod) toTarget:self withObject:nil];
#try
{
NSArray *Keys =[[NSArray alloc] initWithObjects:#"LoginName",#"PassWord",nil];
NSArray *KeyValue =[[NSArray alloc] initWithObjects:UserName,Password,nil];
operationName=[[NSString alloc] init];
operationName =#"ClientLogin";
NSURL *WebServiceUrl=[WebServiceHelper generateWebServiceHTTPGetURL:url : operationName : Keys: KeyValue];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:WebServiceUrl];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser setDelegate:self];
[parser parse];
[Keys release];
[KeyValue release];
[WebServiceUrl release];
[NSThread detachNewThreadSelector:#selector(dismissAlertMethod) toTarget:self withObject:nil];
}
#catch (NSException * e)
{
[NSThread detachNewThreadSelector:#selector(dismissAlertMethod) toTarget:self withObject:nil];
}
return Result;
}
-(void)showAlertMethod
{
NSAutoreleasePool *pool1=[[NSAutoreleasePool alloc]init];
progressAlert = [[UIAlertView alloc] initWithTitle:#"Signing in..." message:#"Please wait..." delegate:nil cancelButtonTitle: nil otherButtonTitles:nil];
CGRect alertFrame = progressAlert.frame;
UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.frame = CGRectMake(135,alertFrame.size.height+75, alertFrame.size.width,30);
activityIndicator.hidden = NO;
activityIndicator.contentMode = UIViewContentModeCenter;
[activityIndicator startAnimating];
[progressAlert addSubview:activityIndicator];
[activityIndicator release];
[progressAlert show];
[pool1 release];
}
-(void)dismissAlertMethod
{
NSAutoreleasePool *pool2=[[NSAutoreleasePool alloc]init];
[progressAlert dismissWithClickedButtonIndex:0 animated:YES];
[pool2 release];
}
A little hard to read your code, but: you cannot do UI from a thread. Your alert must be created and shown from the main thread.

Resources