I have implemented a UIActivityIndicator that shows up in one part of my program but not another. I have the activity indicator come up while i am loading a table, however, i am trying to get it to start animating again after the user has clicked a button and is waiting for the table to reload. The table reloads, but no indicator. Here is the code.
- (void)viewWillAppear:(BOOL)animated {
CGRect frame = CGRectMake (120.0, 185.0, 80, 80);
activity = [[UIActivityIndicatorView alloc] initWithFrame: frame];
activity.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[activity startAnimating];
[navigationUpdateFromDetail.window addSubview: activity];
[super viewWillAppear:animated];
}
It comes up for that part. However, for the next part it does not want to seem to come up.
- (IBAction) btnGreaterTen_clicked :(id)sender {
self.searchDistance = [NSNumber numberWithDouble : 10];
CGRect frame = CGRectMake (120.0, 185.0, 80, 80);
activity = [[UIActivityIndicatorView alloc] initWithFrame: frame];
activity.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
[navigationUpdateFromDetail.window addSubview: activity];
[activity startAnimating];
NSLog(#" search value after change %#", [searchDistance description]);
[self getSetDisplay];
[activity stopAnimating];
}
That button changes a variable and is suppose to start the animation, but it does not. I have changed the color to make sure it was not just blending in, so that is not the solution. I tried to recreate the same object, but still no luck.
Thank you in advance.
That won't work, because the animation will only show when the main application loop is "running". In your code, you're blocking the main thread by calling [self getSetDisplay].
You should load your data asynchronously to make this work (in a background thread). Then you can call startAnimating, start your thread, and when the thread finishes, stop the animation.
This has been bugging me for ages, and I just found that when using a search display controller I had to add the activity indicator as a subview of the search results to get it to show. In my viewDidLoad, I put...
// create activity indicator
activityIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[self.searchDisplayController.searchResultsTableView addSubview:activityIndicator];
When I want to start animating, i put...
[activityIndicator setCenter:CGPointMake(self.searchDisplayController.searchResultsTableView.frame.size.width/2.0f, self.searchDisplayController.searchResultsTableView.frame.size.height/2.0f)];
[activityIndicator startAnimating];
Hope this helps someone.
try adding
activity.hidden = NO;
just before
[activity startAnimating];
Related
Now i am working in iPhone application, Using UIImageView to create a animation and it's working fine, then i tried to call one method for when the animation once completed then the button to show on the screen, but that button showing first then the animation starts, i want once animation completed then the button showing on the screen, how to fix this issue? please help me
Thanks in Advance
I tried this for your reference:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray * imageArray = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"cardopen.png"],
[UIImage imageNamed:#"middlecard.png"],
[UIImage imageNamed:#"thirdcard.png"],
[UIImage imageNamed:#"a.png"],
[UIImage imageNamed:#"cardopen1.png"],
[UIImage imageNamed:#"middlecard2.png"],
[UIImage imageNamed:#"thirdcard1.png"],
[UIImage imageNamed:#"2.png"],
nil];
UIImageView * cardsImage = [[UIImageView alloc] initWithFrame:CGRectMake(10, 0, 400, 300)];
cardsImage.animationImages = imageArray;
cardsImage.animationDuration = 8.0;
cardsImage.animationRepeatCount=1; // one time looping only
[self.view addSubview:cardsImage];
[cardsImage startAnimating];
[self method1]; // To Call a method1 to show UIButton (Once the animation is completed, then to call a method1)
}
-(void)method1
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame=CGRectMake(10, 40, 50, 50);
[self.view addSubview:btn];
}
(Why doesn't anybody understand the concept of asynchronous methods? Is this that hard?)
[cardsImage startAnimating];
returns immediately, not after the animation finished. You have to set an explicit timeout:
NSTimer *tm = [NSTimer scheduledTimerWithTimeInteral:imageView.animationDuration * imageView.animationCount // assuming animationCount is not 0
target:self
selector:#selector(method1)
repeats:NO
userInfo:nil];
Use
[self performSelector:#selector(method1) withObject:nil afterDelay:8.0];
instead of [self method1];
This is because you are putting all of your code in ViewDidLoad. The whole method will be processed . Plus you have your animation duration set to 0.8 which is a slow animation.So the button would appear normally and the animation would continue along with it and then even more. So what you actually have to do is use an NSTimer or use the answers provided to you here :)
I am using a scrollview to display a viewcontrollers view. if the user reaches the end of the cached views my method reloads the new views. My NSLogs say that the method is finished but it takes additional 5 seconds to display the view.
I think that the [scrollView addSubview:vc.view] is very very slow but I found nothing to improve it.
the whole method gets called in -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
scrollView.userInteractionEnabled = NO;
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityIndicator setFrame:CGRectMake((320.f*index)+135.f, 151, 50, 50)];
[activityIndicator setHidesWhenStopped:YES];
[activityIndicator startAnimating];
[scrollView addSubview:activityIndicator];
MBBAppDelegate *delegate = (MBBAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate fetchDealsWithFilter:dealFilter fromIndex:index toIndex:(index+3) onSuccess:^(id object){
MBBDealList *list = object;
int i = 0;
ProductDetailViewController *vc;
for (MBBDeal *deal in [list deals]) {
NSLog(#"start %i",i);
int indexInArray = i;//[list.deals indexOfObject:deal];
if (indexInArray+index >= numDeals) {
return;
}
vc = [[ProductDetailViewController alloc] init];
//fetch the deal and insert
vc.numberOfDeals = numDeals;
vc.dealIndex = index+1+indexInArray;
vc.dealFilter = dealFilter;
vc.deal = deal;
vc.view.frame = CGRectMake(320.f*(index+indexInArray), 0.f, 320.f, 436.f);
[scrollView addSubview:vc.view];
[productDetailViewControllers insertObject:vc atIndex:(index+indexInArray)];
i++;
}
[activityIndicator stopAnimating];
scrollView.userInteractionEnabled = YES;
}];
}
Does anyone know how I can improve my method?
What I can understand from your problem is that, the activity indicator that you have used to show the data fetch process is not used properly.
You data fetch process is still working, even after the activity indicator disappears.
You can do 2 things for that:
ether call the data fetch method in background using performSelectorInBackground method or place the activity indicator in the app delegate where you have created your data fetch method.
I have an image picker to pick multiple images from the photo library. The picked photos are resized and saved to file in imagePickerController:didFinishPickingMediaWithInfo:. It takes a few seconds.
Could I put an indicator on the view?
I have tried to use addSubview:indicatorView in imagePickerController:didFinishPickingMediaWithInfo: method. But indicatorView doesn't appear. It gets dismissed with the imagePickerView.
You should add the UIActivityIndicatorView at the top of the view hierarchy or it will get dismissed with the UIPickerViewController, unless you use a callback after the resize operation and in the callback you dismiss the UIImagePickerController.
Or you could use a progress HUD like SVProgressHUD.
Hope this helps =)
We did a little chat session and solved this way:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIView *primaryImage = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,460)];
primaryImage.backgroundColor = [UIColor redColor];
primaryImage.alpha =0.9;
UIView *secondaryImage = [[UIView alloc] initWithFrame:CGRectMake(0,0,70,70)];
secondaryImage.center = CGPointMake(160, 240);
secondaryImage.backgroundColor = [UIColor blackColor];
secondaryImage.alpha = 0.9;
secondaryImage.layer.cornerRadius = 12;
[primaryImage addSubview:secondaryImage];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
indicator.center = CGPointMake(35, 35);
[indicator setHidesWhenStopped:NO];
[secondaryImage addSubview:indicator];
[indicator startAnimating];
[indicator release];
[secondaryImage release];
[picker.view addSubview:primaryImage];
[primaryImage release];
});
// Put here the code to resize the image
dispatch_async(dispatch_get_main_queue(), ^{
// Dismiss the picker controller
});
});
I am trying to put a UIActivityIndicatorView on a black background, however I can't see it spinning. Why is this? Here's what I have:
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indicator setCenter:CGPointMake(0, 15)];
[indicator setBackgroundColor:[UIColor blackColor]];
[indicator startAnimating];
[indicator hidesWhenStopped];
Are you actually adding your ActivityIndicator as a subview somewhere ?
If not you should add it in viewDidLoad or somewhere else appropriate using:
[self.view addSubview:indicator]
Also I'm not sure if setBackgroundColor will have the desired effect you're looking for. I achieve this using a UIImageView and a black image with radial corners. I also like to set the Alpha value of the black image to about 75 percent. Then whenever I call startAnimating I also show the imageView, and when I call stopAnimating I hide the imageview.
I want to show the activity indicator on tap gesture and also navigate from current viewcontroller to next viewcontroller I have written code on tap gesture method my code is -
- (void)tapToAutoFocus:(UIGestureRecognizer *)gestureRecognizer
{
textLabel.hidden = YES;
indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(140, 150, 30, 30)];
[indicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.view addSubview:indicator];
[indicator startAnimating];
AccountAnfordernViewController *accountAnfordernViewController = [[AccountAnfordernViewController alloc]init];
[self.navigationController pushViewController:accountAnfordernViewController animated:YES];
[accountAnfordernViewController release];
}
It navigates to next view controller but indicator are not showing, I want when it navigate to nextviewcontroller at that time indicator also should be show for some time and then navigate to next view controller. What should I do for that?
I suspect you need to do something like this:
- (void)tapToAutoFocus:(UIGestureRecognizer *)gestureRecognizer
{
textLabel.hidden = YES;
indicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(140, 150, 30, 30)];
[indicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.view addSubview:indicator];
[indicator startAnimating];
[self performSelector:#selector(pushAccountAnfordern) withObject:nil afterDelay: 0.1];
}
- (void) pushAccountAnfordern;
{
AccountAnfordernViewController *accountAnfordernViewController = [[AccountAnfordernViewController alloc]init];
[self.navigationController pushViewController:accountAnfordernViewController animated:YES];
[accountAnfordernViewController release];
}
You can vary the delay. And, indeed, 0.0 may be just fine. This way of doing it lets the current run loop end, giving a chance for the spinner to start showing before starting the next bit of code. For a different approach (with potential side effects) to forcing the spinner to start before the current run loop ends this this SO question.