IOS - How to avoid keyboard from hiding when uiwebview reloads - iphone

I have a webview that loads a web chat client.
As every chat, the page has a textfield to input text.
The problem is that when the user opens the keyboard it is automatically hidden after a short time due to several ajax requests that are reloading the page. This becomes really annoying for the user as he or she can't input a complete sentence before the keyboard hides.
I don't know why, this only happens in iPhone 4S and iPhone 5. In iPhone 4, 3GS, and Simulator everything works ok.
I have tried to use shouldStartLoadWithRequest to catch the request and load it after the user hides the keyboard, but this ruins the chat session.
I tried to "hang" the request with a Thread sleep in the same method, but it happens in the Main Thread so it freezes the entire application.
Is there a way I can simply avoid the keyboard from hiding?

So after a long research I found a way to do it, its not the best but it helped me a lot.
First use DOM to check if the webView firstResonder
- (BOOL)isWebViewFirstResponder
{
NSString *str = [self.webView stringByEvaluatingJavaScriptFromString:#"document.activeElement.tagName"];
if([[str lowercaseString]isEqualToString:#"input"]) {
return YES;
}
return NO;
}
Then respond to UIWebViewDelegate method shouldStartLoadWithRequest, and return NO if UIWebView is first responder
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if([self isWebViewFirstResponder] &&
navigationType != UIWebViewNavigationTypeFormSubmitted) {
return NO;
} else {
return YES;
}
}

You can use Notification center inside your DidLoad method to listen when the keyboard will hide like this:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
- (void) keyboardWillHide{
[webView becomeFirstResponder];
}
which will make the web view first responder and show the keyboard again. I haven't tried it myself so hopefully it will do the trick..

if your text field is on UIView
You can use web view Delegate method
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[textField becomeFirstResponder];
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
[textField becomeFirstResponder];
}
otherwise if textField is on UIWebView then replace textField with webView as shown below.
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[webView becomeFirstResponder];
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
[webView becomeFirstResponder];
}

Related

ios - UIWebView DidFinishLoad not being called

I have a UIWebView that works ok. The delegate is working. When I open a URL, events shouldStartLoadWithRequest and webViewDidFinishLoad are fired.
But when for example I click on a Google search result, only shouldStartLoadWithRequest is fired, and webViewDidFinishLoad is never called.
This is causing problems because if I put a "loading..." indicator on shouldStartLoadWithRequest, in these cases the indicator still remains even after the page is correctly loaded.
Any idea why this is happening?
in .h file add <UIWebViewDelegate>
and in .m:
yourWebview=[[UIWebView alloc]init];
yourWebview.delegate=self;
When you click on search, the navigationType is UIWebViewNavigationTypeFormSubmitted. So in this case, the return type should be YES. If it is not, webViewDidFinishLoad method is not fired.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"shouldStartLoadWithRequest");
if ( navigationType == UIWebViewNavigationTypeLinkClicked ){
NSLog(#"UIWebViewNavigationTypeLinkClicked");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeFormSubmitted ) {
NSLog(#"UIWebViewNavigationTypeFormSubmitted");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeBackForward) {
NSLog(#"UIWebViewNavigationTypeBackForward");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeFormResubmitted) {
NSLog(#"UIWebViewNavigationTypeFormResubmitted");
return YES;
}
if (navigationType ==UIWebViewNavigationTypeReload) {
NSLog(#"UIWebViewNavigationTypeReload");
return YES;
}
return YES;
}
This problem is usually found on ipad applications .... but you can solve your problem by using [self performselector:afterdelay] , you have to check in selector method whether webview has loaded or not using [m_pWebview loaded]; and according to that perform indicator stopping .... it's not the proper solution but it works .......
Not an expert on Google API, but as I suspected this might be your reason.

ios uiwebview stop request when shouldstartloadwithrequest

I am receiving shouldstartloadwithrequest event and I need to stop request for some conditions. How to stop uiwebview request when shouldstartloadwithrequest? Thank you
Check for the condition, then return NO in shouldStartLoadWithRequest. Make sure to set delegate appropriately and include the UIWebViewDelegate protocol in the interface of the delegate class.
You can invoke the stopLoading method for the UIWebView. Below code will check if the webview is loading and stop it.
if([webView isLoading]) {
[webView stopLoading];
}
EDIT: After re-reading your question, I understood you want to return NO in the request to stop it from beginning to load, so you would do something like:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
//Check your condition:
if(myCondition == TRUE)
return NO;
return YES;
}

Getting signals from uiwebview

Is there a possibility to get a signal from a uiwebview?
In my case, I display a webpage in the webview. When the user presses a button on the website, my App should (also) react to this.
Thanks for help
Yes you can do this. Implement
– webView:shouldStartLoadWithRequest:navigationType:
This delegate . This method gets called whenever your webview is about to make a request. So now when someone clicks a button on your webpage, you will get a call to this method. After you catch this call, you can choose to do whatever you want with it. Like redirect the link through your own servers, or log a request to your server about user activity etc.
Example - here you are trying to intercept any links clicked on your webpage & pass it through myMethodAction first.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
if(navigationType == UIWebViewNavigationTypeLinkClicked)
{
if(overrideLinksSwitch.on == TRUE)
{
[self myMethodAction];
[myWebView stopLoading];
return YES;
}
else
{
return YES;
}
}
return YES;
}
Hope this helps...
UIWebViewDelegate provide several methods. I had used one of them like this
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked ) {
// do stuff
return NO;
}
return YES;
}

Open Link in UIWebview not UIShared Application

I have been having a rough time trying to open links that a user clicks in a simple web view instead of multitasking and going to safari. It is quite a pain for my users to have to leave the app every time a link is clicked and I know it is probably quite simple but still am having a terrible time making this happen. Here is the code I am using but still when the link is clicked it opens safari.
If anyone can help point me in the right direction I would be greatly appreciative! Thank you!
- (void) handleURL:(NSURL*)url
{
[web loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"%#"]]];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest
*)request
navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"expected:%d, got:%d", UIWebViewNavigationTypeLinkClicked, navigationType);
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[UIApplication sharedApplication] ;
return NO;
}
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[web loadRequest:[NSURLRequest requestWithURL:[NSURL
URLWithString:replyTweetText.text]]];
return YES;
}
}
I'm not sure what this bit does:
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[UIApplication sharedApplication] ;
return NO;
}
The line [UIApplication sharedApplication]; creates and returns the singleton application instance. You aren't doing anything with it.
Also, both if statements are identical, so only the first will ever be hit and the method returns NO. There is no default returned value, which is bad for a non-void function. Try this instead:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
return YES;
}

iPhone MotionShake Stops Working After Clicking Link

I have an app that displays a UIWebView after the user shakes the phone. It works perfectly until the user clicks a link in the webview. Once the user clicks a link, they must click white space in the screen to get the shake function to start working again.
As you can see below, I have included both the canBecomeFirstResponder, and the webViewDidFinishLoad functions. Please help!
#import "phonetiltViewController.h"
#implementation phonetiltViewController
-(void)viewDidAppear:(BOOL)animated {
[self becomeFirstResponder];
}
-(void)viewDidDisappear:(BOOL)animated {
[self resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder
{ // Shake gesture pops to top. If you don't want this override and
return YES;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake) {
[webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString:#"http://www.google.com"]]];
}
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self becomeFirstResponder];
}
Then try UIAccelerometer. You can use its delegate method like this
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration{
if(acceleration.x>1.5 || acceleration.y>1.5 || acceleration.z>1.5){
//load page}