All
I am trying to run UIActivityIndicator for a 5 seconds on viewdidappear method .But how do i give a time limit for activity indicator(5 seconds) ?
This is the code for UIActivityIndicator
UIActivityIndicatorView *activityView=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.center=self.view.center;
[activityView startAnimating];
[self.view addSubview:activityView];
With one line and no additional dependencies & conditions:
[activityView performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:5.0];
Set activity view to hide automatically when stopped
activityView.hidesWhenStopped = YES;
And hide it after 5s like this:
[activityView performSelector:#selector(stopAnimating) withObject:nil afterDelay:5.0];
This will allow you to start animation again by just calling startAnimating if you need so in the future and keep pointer to the UIActivityIndicatorView
If you just need to show activity indicator once and will not use it anymore, Alexanders answer will suit best to your needs
Use NSTimer for 5 sec.
In the call back method of timer stop the animation
try this code,
-(void)viewDidAppear:(BOOL)animated
{
UIActivityIndicatorView *activityView=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityView.center=self.view.center;
[self.view addSubview:activityView];
[activityView startAnimating];
activityView.tag=1111;
[activityView release];
}
[activityView performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:5.0];
-(void)removeFromSuperview
{
UIActivityIndicatorView *activityView=(UIActivityIndicatorView*)[self.viewviewWithTag:1111];
[activityView stopAnimating];
[activityView removeFromSuperview];
}
Related
I am creating a UITableview inside a subview. For populating table I am using some jsonget request. During the process I want to show an activity indicator. I am not getting why it's not showing.
Sample code:
activityIndicator1 = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator1.center = CGPointMake([[UIScreen mainScreen]bounds].size.width/2, [[UIScreen mainScreen]bounds].size.height/3);
[self.window addSubview:activityIndicator1];
activityIndicator1.color=[UIColor greenColor];
[self bringSubviewToFront:activityIndicator1];
[UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE;
[activityIndicator1 startAnimating];
Problem is activity indicator not showing.
Thanks and Regards
Vikas
You need to add activityIndicator1 in your subvview.
i.e.
[self.subView addSubView: activityIndicator1];
activityIndicator1's center should be your subview's center.
activityIndicator1.center = subView.center;
Hope this helps.
Thanks
UIActivityIndicator's hidesWhenStopped property is YES by default. Also, it's stopped by default. So your activity indicator is just hidden. Add this code:
activityIndicator1.hidden = NO;
do this instead
UIView* WaitingView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
WaitingView.backgroundColor=[UIColor blackColor];
WaitingView.alpha=0.5;
UIActivityIndicatorView* activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:
UIActivityIndicatorViewStyleWhiteLarge ];
[activityView setCenter:CGPointMake(self.view.frame.size.width/2,self.view.frame.size.height/2)];
[activityView setContentMode:UIViewContentModeCenter];
[WaitingView addSubview:activityView];
[self.view addSubview:WaitingView];
[activityView startAnimating];
When you're refreshing a table with fresh data from an api request, a common and handy tool is UIRefreshControl, which will show as an ActivityIndicator spinning, when the user pulls the table to refresh, while making the call to pull the fresh data.
#property (strong, nonatomic) UIRefreshControl *refreshControl;
then within your viewDidLoad create the refreshControl and add the target action
-(void)viewDidLoad{
[super viewDidLoad]
self.refreshControl = [[UIRefreshControl alloc]init];
[self.refreshControl addTarget:self action:#selector(refreshTable) forControlEvents:UIControlEventValueChanged];
[yourTableView addSubview:self.refreshControl];
}
By pulling the table in a downward motion, the activity indicator will show and the call to refresh the table will be made.
-(void)refreshTable{
// Here your call to pull data from your API to refresh the data
// ** Your code here to pull in your JSON data and update your datasource **
//Once the data has been retrieved or failed to retrieve, call this to end the refreshing
[self.refreshControl endRefreshing];
}
if this is what you're trying to recreate, I hope this helps.
Note - user will need to pull the table in a downward 'pull-to-refresh' action to activate this of course
add this in your .h file,
#property(nonatomic, retain) UIActivityIndicatorView *indicator;
than add this code in your button click method,
indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.frame = CGRectMake(0.0, 0.0, 60.0, 60.0);
indicator.color = [UIColor colorWithRed:0.949 green:0.571 blue:0.558 alpha:1.000];
[indicator setBackgroundColor:[UIColor colorWithRed:1 green:1.000 blue:1 alpha:1.000]];
indicator.center = self.view.center;
[self.view addSubview:indicator];
[indicator bringSubviewToFront:self.view];
[UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE;
[indicator startAnimating];
than stop indicator where you want using,
[indicator stopAnimating];
hope this will help you.
In my code, I initialize a UIActivityIndicator, and add it as a subview, but it never appears. What's going wrong?
-(void) update {
UIActivityIndicatorView *activityView=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.center=self.view.center;
[self.view addSubview:activityView];
[activityView startAnimating];
/** Stuff to access to server, this stuff works correctly.*/
[activityView stopAnimating];
}
As you are starting and stoping the activity as same runloop so it will not get change to update the UI.You are doing all server stuff on same synchronously than you are blocking the runLoop and do not giving time to activity indicator to start.You should start server stuff on next runLoop so activity indicator will get time to start.So use performSelector with delay 0.0 it will start the activity indicator and than perform your server stuff on immediate next runloop and than stop the activityInddicator
-(void) update {
UIActivityIndicatorView *activityView=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.center=self.view.center;
[self.view addSubview:activityView];
[activityView startAnimating];
//Use performSelector with 0.0 so activity indicator starts
[self performSelector:#selector(thisWillStartAtNextRunLoop) withObject:nil afterDelay:0.0];
}
-(void)thisWillStartAtNextRunLoop{
/** Stuff to access to server, this stuff works correctly.*/
[activityView stopAnimating];
}
Edit execute it on main thread as all UI updation must be on main thread
Try
-(void) update {
dispatch_async(dispatch_get_main_queue(), ^{
UIActivityIndicatorView *activityView=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.center=self.view.center;
[self.view addSubview:activityView];
[activityView startAnimating];
});
/** Stuff to access to server, this stuff works correctly.*/
}
I have a method to retrieve data from an external url, load it into an array from JSON format, and populate a UITableView. It works fine, but there is no indication to the user that something is happening while the data is downloaded.
- (void)viewDidLoad
{
[super viewDidLoad];
[self retrieveDataC];
}
Here is the code that I tried for viewDidLoad which adds a spinner animation while downloading. I'm attempting to put retrieveDataC on a background thread and when it completes, I would like the view to continue executing as though I didn't implement the multi-threading in the example above.
- (void)viewDidLoad
{
[super viewDidLoad];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
[self.view addSubview:spinner];
[spinner startAnimating];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self retrieveDataC];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
});
});
}
The loading spinner displays correctly for a brief moment, however after the process is done I'm left with a blank table as though I have not called [self retrieveDataC] to begin with. Any suggestions, advice? Am I setting up the background process correctly?
Thank you
EDIT:
Here's what ended up working -
- (void)viewDidLoad
{
[super viewDidLoad];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake(160, 240);
[self.view addSubview:spinner];
[spinner startAnimating];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self retrieveDataC];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner stopAnimating];
[self.collectionView reloadData];
});
});
}
Do you call [self.tableView reloadData] after you received the data?
I have an app with a table view controller in which a user selects a US state, a web service is called and data is displayed for that state in the destination table view controller. Since the web service can take some time to complete I want an activity indicator. Since there will be no temporary data to display, I need this to be processed synchronously. So my task is pretty simple: start the activity indicator, call the web service, and after it completes, stop the activity indicator.
I am obviously doing something wrong and no activity indicator ever displays.
Here is the code from my destination table view controller's viewDidAppear method:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self.tableView bringSubviewToFront:spinner];
spinner.hidesWhenStopped = YES;
spinner.hidden = NO;
[spinner startAnimating];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
[self.tableView reloadData];
[spinner stopAnimating];
}
Header:
#property (strong, nonatomic) UIActivityIndicatorView *spinner;
GaugeList is the object which makes the web service call.
Can someone tell me how to get an activity indicator view to appear? Thanks!
You forgot to add spinner on table view. Your code should look as follows:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spiner.center = //set some center
[self.tableView addSubview: spinner];
[self.tableView bringSubviewToFront:spinner];
spinner.hidesWhenStopped = YES;
spinner.hidden = NO;
[spinner startAnimating];
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
[self.tableView reloadData];
[spinner stopAnimating];
}
Also you send requests to a web service in main thread. This is bad practice. I would suggest something like following:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spiner.center = //set some center
[self.tableView addSubview: spinner];
[self.tableView bringSubviewToFront:spinner];
spinner.hidesWhenStopped = YES;
spinner.hidden = NO;
[spinner startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[spinner stopAnimating];
});
});
}
At first you should add activity indicator to some view to show it. But you can not add it to UITableView, because UITableView is subclass of UIScrollView and you will see floating activity indicator. The best way in your case is to add activity indicator to navigation bar, etc. Or if you want to disable table view you should write something like this:
- (void)viewDidLoad {
[super viewDidLoad];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
UIView *dummyView = [[UIView alloc] init];
dummyView.frame = self.tableView.bounds;
dummyView.alpha = 0.5f;
dummyView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
dummyView.userInteractionEnabled = YES;
dummyView.backgroundColor = [UIColor blackColor];
[dummyView addSubview:activityIndicator];
activityIndicator.center = dummyView.center;
[self.tableView addSubview:dummyView];
}
Try using self.spinner instead of using spinner.
In a method that can take up to several seconds i have:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(135,140,50,50)];
spinner.color = [UIColor blueColor];
[spinner startAnimating];
[_mapViewController.view addSubview:spinner];
// lots of code
[spinner removeFromSuperview];
The spinner doesn't show up. Probably since the screen doesn't get update at that time.
How can i get around this problem?
Use GCD:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(135,140,50,50)];
spinner.color = [UIColor blueColor];
[spinner startAnimating];
[_mapViewController.view addSubview:spinner];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// lots of code run in the background
dispatch_async(dispatch_get_main_queue(), ^{
// stop and remove the spinner on the main thread when done
[spinner removeFromSuperview];
});
});