I am trying to get the activity indicator to stop animating once the view has loaded. Currently, the view has loaded but the activity indicator does not stop circulating. Here is my code:
UIWebView *elionWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 44, 375, 579)];
[self.view addSubview:elionWebView];
elionWebView.delegate = self;
//Start the Activity Indicator
[self webViewDidStartLoad:elionWebView];
//Load Website
NSString* url = #"https://google.com/";
NSURL* nsUrl = [NSURL URLWithString:url];
NSURLRequest* request = [NSURLRequest requestWithURL:nsUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[self webViewDidFinishLoad:elionWebView];
[elionWebView loadRequest:request];
}
-(void)webViewDidStartLoad:(UIWebView *)webView {
//Start the Activity Indicator
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.center = CGPointMake(187.5, 370);
[activityView startAnimating];
activityView.tag = 100;
[self.view addSubview:activityView];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[self.view viewWithTag:100].hidden = YES;
There are a few problems with your code. Firstly, NSURLRequest does not actually load the URL. There are different ways to do the download. Look at NSURLConnection for the simplest way to do a synchronous download.
Secondly, I suggest you declare your UIActivityIndicatorView as a member variable of your class rather than tagging the view.
There are UIActivityIndicatorView methods for starting and stopping animations. You should use stopAnimating to stop the animation. If you have set the property hidesWhenStopped to YES on the view, then you will get the behavior you want. If you do not want the indicator after animation has stopped, use removeFromSuperview to get rid of it.
Related
I want to add a subView to this WKWebView with this content (https://www.windytv.com/?-34.816,138.608,5). so that the subView can be panning along with the webview (imagine there's landmark view being panning along), but I could do it.
I tried many ways as follows:
I add a landmarkView to different subViews of the webView, failed.
1.1 For example:
[self.webView addSubView:landmarkView];
1.2 Or:
[self.webView.scroolView addSubView:landmarkView];
1.3 Or:
[self.webView.scroolView.subViews.firstObject addSubView:landmarkView]; // In viewDidAppear
The interesting thing here is the view hierachy of WKWebsite will change in viewDidAppear. It gets more subView like "WKContentView".
Followed by 1., I try to add a gestureView to pass the gesture to move the landmarkView, failed. The action of the gesture did not procceed.
1.1. For example, I add on the super view of webView.
[self.view addSubView: baseView];
[self.baseView addSubView: webView];
self.panGestureRecognizer.cancelsTouchesInView = NO;
[webView addGestureRecognizer: self.panGestureRecognizer];
Or, I add on the subView of webView.
[self.view addSubView: webView];
[self.webView addSubView: gestureView];
gestureView.backgroundColor = [UIColor clearColor];
self.panGestureRecognizer.cancelsTouchesInView = NO;
[gestureView addGestureRecognizer: self.panGestureRecognizer];
Anyone familiar with WKWebView?
Except for UIGesture, Is there other ways to distribute a touch to many views?
If I could override the touchesBegan method in one of the subViews, it should be much easier. And I think hitTest still work only on a view.
The general
- (void)viewDidLoad
{
UIView *landmarkView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 200, 200)];
landmarkView.backgroundColor = [UIColor redColor];
NSString *path = #"https://www.windytv.com/?-37.331,145.102,7";
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
[self.view addSubView: self.webView];
[self.webView.scrool addSubView:landmarkView]; // This is one of the failed attempts.
}
It can be solved by adding a panGesture with this delegate method.
The trick is introduced here:
UIPanGestureRecognizer on MKMapView?
I want the progressView working while my URL is loading. What should I do for that?
here's my .m code:
-(void)openURL{
UIWebView *webView = [[UIWebView alloc] init];
[webView setFrame:CGRectMake(0, 0, 320, 460)];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com"]]];
[[self view] addSubview:webView];
}
- (IBAction)goto:(id)sender {
[self openURL];
}
Implement UIWebViewDelegate, specifically:
-(void)openURL{
UIWebView *webView = [[UIWebView alloc] init];
webView.delegate = self;
// ... rest of method as above ...
}
- webViewDidStartLoad:(UIWebView *)webView {
// Start progress.
}
- webViewDidFinishLoad:(UIWebView *)webView {
// Stop progress.
}
You could do something like this
[progressView startAnimating];
dispatch_async(dispatch_get_main_queue(), ^{
[webView loadRequest:yourRequest];
[progressView stopAnimating];
[progressView removeFromSuperView];
}
This will start the progress view before the operation begins, and will stop and remove it when it finishes.
I have a method which is calling a external webservice.
Now I want to show an UIActivityIndicatorView in the middle of the screen, while the webservice-call is running. I call the webservice-method asynchronously. But with my code which you will find at the bottom, I have two problems:
the current view is not locked. That means, that the user can interact with the current view. I want to block all till the animation is stopped
the animation is not centered
Here is my code which I have tried now:
-(void)saveDataOnServer {
UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(225, 115, 30, 30)];
[activity setBackgroundColor:[UIColor clearColor]];
[activity setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[self.view addSubview:activity];
[activity startAnimating];
// ...
[NSURLConnection sendAsynchronousRequest: request
queue: queue
completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) {
[activity stopAnimating];
// ...
}
];
}
You have to put another view when activity indicator start :
UIView *overlayView;
overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
[[UIApplication sharedApplication].keyWindow addSubview:overlayView];
And remove that view(overlayView) when activity indicator stops :
[overlayView removeFromSuperview];
This OverlayView will cover current view.So user can not interact with current view.
Hi there i have a good solution for you ..
there i a library called MBProgressHUD
which does all you want , WITH Style
This is The link for the library HERE
And its easy to use .. here is an example i used
self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
self.hud.mode = MBProgressHUDModeIndeterminate;
self.hud.labelText = #"Fetching News";
//self.hud.detailsLabelText=#"Fetching News";
self.hud.dimBackground = YES;
and there is a demo you can see .. Cheers :D
When moving from one view to another, I want in my second view as long as the image is being downloaded to see a spinner (so that the second view will open instantly not take any time at all, and the user waits for the spinner to finish).
Here is my code:
In the second View, the one that opens:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center=CGPointMake(160.0,240.0 );
spinner.hidesWhenStopped=YES;
[self.view addSubview:spinner];
[spinner startAnimating];
NSString *urlString=[NSString stringWithFormat:#"http://mysite.com/projects/test/test.jpg"];
NSLog(#"URL is:%#",urlString);
NSURL *url=[NSURL URLWithString:urlString];
[more_info_image setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
[spinner stopAnimating];
}
I do not see the spinner at all. i do not think that this is because my internet connection is so fat. On the other hand, I see a little delay when a button is pressed and waiting for the view to open - like that it is that time when it tries to download the image.
I want to open the view, have the spinner, download the image and then let the spinner go away.
Must I change anything?
You might not be seeing the UIActivityIndicatorView since you are using [NSData dataWithContentsOfURL:url] on the main thread. This is blocking the main thread from displaying the UIActivityIndicatorView until after the image is downloaded, and by that point you are removing it.
You might want to do something like:
but make sure you define spinner in your *.h file for this to work.
- (void)viewDidLoad
{
...
//This code will make downloadImage run in the background thread
[self performSelectorInBackground:#(downloadImage) withObject:nil]
...
}
- (void) downloadImage{
NSLog(#"URL is:%#",urlString);
NSURL *url=[NSURL URLWithString:urlString];
UIImage *downloadedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
//This code will make setImage run in the main thread since it is changing UI
[more_info_image performSelectorOnMainThread:#selector(setImage:) withObject:downloadedImage waitUntilDone:NO];
//This code will make stopAnimating run in the main thread since it is changing UI
[spinner performSelectorOnMainThread:#selector(stopAnimating) withObject:nil waitUntilDone:NO];
}
The other way is to use Grand Central Dispatch and do something like:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center=CGPointMake(160.0,240.0 );
spinner.hidesWhenStopped=YES;
[self.view addSubview:spinner];
[spinner startAnimating];
//This is the new GCD code
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
//This code will run on a background thread
NSString *urlString=[NSString stringWithFormat:#"http://mysite.com/projects/test/test.jpg"];
NSLog(#"URL is:%#",urlString);
NSURL *url=[NSURL URLWithString:urlString];
UIImage *downloadedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
dispatch_sync(dispatch_get_main_queue(), ^{
//this code runs on the main thread since it is UI changes
[more_info_image setImage:downloadedImage];
[spinner stopAnimating];
});
});
}
As you are downloading your image in the viewDidLoad method so while the image is downloading it did not loads your view so that's why you are experiencing a delay try this
in your header file add an instance of UIActivityIndicator
UIActivityIndicator *spinner;
in your implementation file do something like this
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
spinner=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center=CGPointMake(160.0,240.0 );
spinner.hidesWhenStopped=YES;
[self.view addSubview:spinner];
[spinner startAnimating];
[self performSelector:#selector(downloadYourImageMethod) withObject:nil afterDelay:1];
}
-(void)downloadYourImageMethod
{
NSString *urlString=[NSString stringWithFormat:#"http://mysite.com/projects/test/test.jpg"];
NSURL *url=[NSURL URLWithString:urlString];
[myIMageview setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
[spinner stopAnimating];
}
modify your code as
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center=CGPointMake(160.0,240.0 );
spinner.hidesWhenStopped=YES;
[self.view addSubview:spinner];
[spinner startAnimating];
[self performSelector:#selector(downloadImage) withObject:nil afterDelay:0.1];
}
-(void)downloadImage
{
NSString *urlString=[NSString stringWithFormat:#"http://mysite.com/projects/test/test.jpg"];
NSLog(#"URL is:%#",urlString);
NSURL *url=[NSURL URLWithString:urlString];
[more_info_image setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
[spinner stopAnimating];
}
Sometimes, it all depends on how you are placing your views. The spinner should the very last thing that's added to the hierarchy in order to be the first in the order when your view loads. This was the issue in my case, I hope this help anyone else that bumps into this answer. :)
I have a UIWebView embeded as a subview which loads an html form from the web. The problem is that when you select one of the text fields it receives the focus, but the keyboard does not display. this only happens on iOS6 if i run this app on iOS 4.3, 5.1 etc it works as expected. Any one have any advice
- (void)viewDidLoad
{
[super viewDidLoad];
webView = [[UIWebView alloc] init];
[webView setUserInteractionEnabled:YES];
[webView setScalesPageToFit:YES];
[webView setKeyboardDisplayRequiresUserAction:YES];
// load url here
NSURL *url = [NSURL URLWithString:redirectUrl];
//URL Requst Object
NSMutableURLRequest *requestObj = [NSMutableURLRequest requestWithURL:url];
[requestObj setHTTPMethod:#"POST"];
[webView loadRequest:requestObj];
UIScrollView* sv = nil;
for(UIView* v in [webView subviews]){
if([v isKindOfClass:[UIScrollView class] ]){
sv = (UIScrollView*) v;
sv.scrollEnabled = NO;
sv.bounces = NO;
}
}
[webView setOpaque:NO];
[webView setBackgroundColor:[UIColor whiteColor]];
webView.delegate = self;
[self.view addSubview:webView];
}
You can use the answer of this question:
Some UITextfields don't respond in iOs6
You have to resingfirstresponder before presentmodalviewcontroller in the the controller where are you calling the view with the problem.
BUT, you also have to resignfirst responder in all previews controllers, that is.
In my case i go from a searchbar to a detail view, and from detail to share in facebook. The view of share in facebook wasn't showing the keyboard, and it was 'cause i wasn't resiginif first responder of search bar.
Hope it helps.