I am making call to two web services simultaneously, i am showing activity indicator at that time. Since either of the service can end first. I am not sure how to hide the activity indicator. I am thinking to use flag. But i am not sure whether that is the better way.Please help me with some better approach.
One easy way is to use AFNetworking library, which takes care of NetworkActivityIndicator for you. You just need to set [[AFNetworkActivityIndicatorManger sharedManager] setEnabled:YES]; in your app delegate.
Otherwise, keeping a counter is a good way to do it. When you start each web request, just increment the counter and decrement the counter in the success or failure block. In those blocks, after decrementing the counter, if the counter is equal to zero, then set isNetworkActivityIndcatorVisible property of [UIApplication sharedApplication] to NO.
Try This.
Add one line Before [self.window addSubview: activityView1]
activityView1.tag = 110;
(You can set any number other than 110 also)
And Write following code to remove:
for(UIView *viewActivityIndicator in [[UIApplication sharedApplication] keyWindow].subviews)
{
if(viewActivityIndicator.tag == 110)
{
[viewActivityIndicator removeFromSuperview];
}
}
If there is no special requirement than use some library instead of managing self.
Some Good Example :
1. SVProgressHUD
2. MBProgressHUD
You need to create a method in AppDelegate.m class
#pragma mark activity indicator view
-(void)showActivityViewer:(NSString* )msg
{
if (activityView1 == nil)
{
[activityView1 release];
activityView1 = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 320, 580)];
activityView1.backgroundColor = [UIColor darkGrayColor];
activityView1.alpha = 0.8;
UILabel* lblLoading=[[UILabel alloc] initWithFrame:CGRectMake(70, 260, 180, 60)];
lblLoading.numberOfLines=0;
lblLoading.text=msg;
lblLoading.backgroundColor=[UIColor clearColor];
lblLoading.textAlignment=UITextAlignmentCenter;
[lblLoading setContentMode:UIViewContentModeBottom];
lblLoading.textColor=[UIColor whiteColor];
[activityView1 addSubview:lblLoading];
[lblLoading release];
UIActivityIndicatorView *activityWheel = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(self.window.bounds.size.width / 2 - 15, self.window.bounds.size.height / 2 - 30, 30, 30)];
activityWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
activityWheel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[activityView1 addSubview:activityWheel];
[activityWheel release];
}
[self.window addSubview: activityView1];
[[[activityView1 subviews] objectAtIndex:0] setText:msg];
[[[activityView1 subviews] objectAtIndex:1] startAnimating];
}
Every time whenever you need to show activity indicator in the whole use this...It automatically manages all the things
To hide the indicator call this method,same in the AppDelegate.m class
-(void)hideActivityViewer
{
[[[activityView1 subviews] objectAtIndex:1] stopAnimating];
[activityView1 removeFromSuperview];
}
Related
Essentially what I'm trying to do here is have a function which sets the alpha of a subview of self.view to 1 (it is hidden by default) which gets called upon pressing a button. i've run into this problem a few times because i declare subviews in viewDidLoad and i don't know of a way to interact with those in a different function (i've tried self.view.subviews[n] but xcode is not happy with that). the only other way i can think of to make this happen is to set self.view equal to the view i want, or maybe even create the view within the function i'm hoping to call with the button (the issue i see with that is potentially the view will not overlay the button, which i want to happen).
here's what i have so far:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *firstBackground = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIView *blackOverlay = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
blackOverlay.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.0];
firstBackground.backgroundColor = [UIColor whiteColor];
UIButton *fakeNotifButton = [UIButton buttonWithType:UIButtonTypeCustom];
[fakeNotifButton addTarget:blackOverlay action:#selector(setupFakeNotifScreen:) forControlEvents:UIControlEventTouchUpInside];
//i haven't finished the button yet, that i don't need any help with
}
-(IBAction)setupFakeNotifScreen:(id)sender {
[UIView animateWithDuration:1.0
delay:0.5
options:UIViewAnimationOptionCurveEaseInOut
animations:^{view = 1.0;} //here is where i want to call blackOverlay
completion:^(BOOL finished){}];
}
#end
edit: i figured it out... didn't even need the blackOverlay view. here's the solution for any future google people... there are probably more efficient ways to do this so i would appreciate anybody who's better than me weighing in:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *fakeNotifButton = [UIButton buttonWithType:UIButtonTypeCustom];
[fakeNotifButton addTarget:self action:#selector(setupFakeNotifScreen:) forControlEvents:UIControlEventTouchUpInside];
fakeNotifButton.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width/2) - 80, 300, 160, 40);
[fakeNotifButton setTitle:#"test" forState:UIControlStateNormal];
[fakeNotifButton setBackgroundColor:[UIColor systemGreenColor]];
fakeNotifButton.layer.cornerCurve = #"continuous";
fakeNotifButton.layer.cornerRadius = 15;
[self.view addSubview:fakeNotifButton];
}
-(void)setupFakeNotifScreen:(UIButton *)sender {
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{self.view.backgroundColor = [UIColor blackColor]; sender.alpha = 0.0;}
completion:^(BOOL finished){}];
}
#end
When you declare
UIView *blackOverlay = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
...that reference is inside the method viewDidLoad, so its existence is confined to that method. It is visible only inside the method, and indeed the reference goes out of existence when the method ends. (The view itself also goes out of existence; you have not put it into the interface.)
If you want a persistent reference to this view, you need to declare a property (or at least an instance variable, aka iva), and set it to this view. You still won't be able to do anything visible with the view if you don't actually put it into the interface.
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.
I have an issue which is not a big deal but driving me crazy.
I have a view which subclasses UITableView.
Pressing on one of the cells leader to an lengthy HTTP requests, which I run on another thread using this code in didSelectRowAtIndexPath:
case SECTION_SEND:
[self addActivityIndicatorToView];
[self performSelectorInBackground:#selector(sendEmail) withObject:nil];
break;
The activityIndicator is behaving correctly. Displaying on the screen and then removing itself when the operation ends. But if the app goes to the background or another tab, the activity indicator disappears, even though the task did not finish.
Here are the methods I am using:
Then:
-(UIActivityIndicatorView*)createActivityIndicator {
//Setting up activity indicator
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.color = [UIColor whiteColor];
spinner.backgroundColor = [UIColor blackColor];
spinner.alpha = 0.8;
CGFloat width = 120;
spinner.frame = CGRectMake(self.tableView.bounds.size.width/2-width/2, self.tableView.bounds.size.height/2-width/2, width, width);
//spinner.center = CGPointMake( [UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height/2);
spinner.layer.cornerRadius = 20;
spinner.layer.masksToBounds = YES;
return spinner;
}
-(void)addActivityIndicatorToView {
//[[[[UIApplication sharedApplication] delegate] window] addSubview:ai];
_ai = [self createActivityIndicator];
[self.tableView.superview addSubview:_ai];
[_ai startAnimating];
}
-(void) removeActivityIndicatorFromView {
[_ai stopAnimating];
[_ai removeFromSuperview];
}
I am calling [self removeActivityIndicatorFromView] when the operation ends.
As I said, it behaves properly unless I leave the screen. I have check my viewdidload and viewwilldisappear viewwillappear and init methods and I have nothing overriding _ai.
Any ideas?
I am developing one iPad application using story board.In my view controller one table is set as the left side and one more view is set as the right side.I need to set one activity controller above the right side view.Which need to start animating when i click the right side table cell and need to stop after 1s.I am using 'didSelectRowAtIndexPath' function for select table cell.How i will set activity indicator for my situation.
In didSelectRowAtIndexPath method you could make a call to below function:-
-(void)setActivityIndcator:(UIView *)view
{
transparentView = [[UIView alloc] init];
transparentView.frame = view.frame; //Provide frame of right side view.
transparentView.alpha = 0.5; //To provide transparent look and feel.
activityInd = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityInd.frame = CGRectMake(transparentView.frame.size.width/2, transparentView.frame.size.height/2, 50, 50); //Change as you want it to be
[transparentView addSubview:activityInd];
[activityInd startAnimating];
[self performSelector:#selector(stopIndicator) withObject:self afterDelay:1];
}
-(void)stopIndicator //This method will be called after delay and would remove view and activityInd
{
[activityInd stopAnimating];
[activityInd removeFromSuperview];
[transparentView removeFromSuperview];
}
Also you could create a subclass of it and use it in any viewcontroller by creating it's object. That why u don't need to write down all function everytime.
use this in this method
didSelectRowAtIndexPath
UIActivityIndicatorView *activityView =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(120, 230, 50, 50);
[self.view addSubview:activityView];
Use the delegate method didSelectRowAtIndexPath of TableView and write the following code into it
UIActivityIndicatorView *activity =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activity.frame = CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/2, 50, 50);
[self.view addSubview:activity];
[activity startAnimating];
Stope this when your work is done and remove it from the view
I had created an application using story board with auto layout support. Now i want to add an loading view on request/response. I had created loading view by code like this
self=[super initWithFrame:f];
[self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.7]];
CGPoint p=[self center];
self.activityIndicator=[[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(p.x-37/2, p.y-32/2, 37, 37)];
[self.activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];
[self addSubview:self.activityIndicator];
lblMsg=[[UILabel alloc] initWithFrame:CGRectMake(p.x-50/2,CGRectGetMaxY(self.activityIndicator.frame), 200, 30)];
lblMsg.text=#"Logging...";
lblMsg.backgroundColor=[UIColor clearColor];
lblMsg.textColor=[UIColor lightGrayColor];
[self addSubview:lblMsg];
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return self;
Now problem is that it is not performing rotation. it is always coming in portrait mode. How can i apply autorotate functionality to it.
may be this will help you try this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
i couldn't find where you are start animating for UIActivityIndicatorView.
[self.activityIndicator startAnimating];
One of the best framework to use for loadingView
1) https://github.com/jdg/MBProgressHUD
You can use NetworkActivityIndicator.
When you sending the request, use
[self setNetworkActivityIndicatorVisible:YES];
and when the response come back, use
[self setNetworkActivityIndicatorVisible:NO];