I have a UIWebView
which loads up an HTML page. This page has two buttons on it, say Exit and Submit. I don't want users to be able to click the Exit button, so once the page has finished loading (ie. webViewDidFinishLoad
is called), I use stringByEvaluatingJavaScriptFromString
to remove one of these buttons, by manipulating the HTML. I also disable user interaction on the UIWebView
on webViewDidStartLoad
, and enable it again on webViewDidFinishLoad
.
The problem I am finding is that stringByEvaluatingJavaScriptFromString
takes a second or two to complete, and it seems to be done in it's own thread. So what is happening is that webViewDidFinishLoad
is called, user interaction is enabled on the UIWebView
, and if the user is quick, they can click the Exit button before stringByEvaluatingJavaScriptFromString
has finished. As stringByEvaluatingJavaScriptFromString
seems to be on it's own thread with no way to know when it's finished (it doesnt call webViewDidFinishLoad
), the only way to completely prevent users from tapping the Exit button that I can see is to only enable user interaction on the UIWebView after some delay, which is unreliable (how can I really know how long to delay for?).
Am I correct in that stringByEvaluatingJavaScriptFromString
is done on it's on thread, and I have no way of being able to tell when it's finished? Any other suggestions for how to get around this problem?
EDIT: In short, what I want to know is if it is possible to disable a UIWebView
while stringByEvaluatingJavaScriptFromString
is executing, and re-enable the UIWebView
when the javascript is finished.
EDIT 2: There's an article here which seems to imply you can somehow poll the JS engine to see when it's finished, but I can't find any other references saying the same thing: http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/
EDIT 3 Based on the answer from Brad Smith, it seems that I actually need to know when the UIWebView has finished loading itself after the javascript has executed. It's looking more and more like I just need to put a delay of sorts in there.
You could have the javascript you are injecting into the page, attempt to navigate the page elsewhere (document.location="foo"), and use webView:ShouldLoadRequest: to look for that request and return no as well as trigger what you need to (and normally returning yes).
stringByEvaluatingJavascriptFromString has to be done when it returns. It may be done on a different thread (probably not since it can change the UI), but the method cannot return the string result until it has a result to return.
After executing stringByEvaluatingJavascriptFromString, you can try below code to solve your problem
webView.userInteractionEnabled = NO;
while (webView.loading) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
webView.userInteractionEnabled = YES;
Let me know its working for you or not.
How about inlining a stub function for the onclick event directly on the html element. You could bind the html element to an onclick event handler function later when it's more appropriate.
<button onclick="function () { };"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With