IOS: how do you detect that the user is changing the text in the UIWebView within the content edited by div

When using UIWebView with editable content, the user can enter their own text into the editable DIV.

Is there a way to fire an event on the ViewController every time the user changes the text being edited (similar to the event the value of the UITextField )?

ViewController needs to know when a user has changed text for two reasons; Know if the user enters any text at all, and resize the UIWebView as the content text increases.

The UIWebView delegate does not seem to include this type of event. This should probably be done through Javascript, but it seems it cannot find the answer. Help!

+6
source share
2 answers

There is no direct way to listen for events from UIWebView, but you can connect them. With iOS7, this is pretty easy since JavaScriptCore.framework (you need to link it to the project):

 JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; ctx[@"myUpdateCallback"] = ^(JSValue *msg) { [self fieldUpdated]; }; [ctx evaluateScript:@"document.getElementById('myEditableDiv').addEventListener('input', myUpdateCallback, false);"]; 

(at the moment I have no way to check the code, but I hope that it works)

Before iOS7 (if you want to support a lower version, you should use this), it was a bit more complicated. You can listen to the webView delegate method webView:shouldStartLoadWithRequest:navigationType: for some custom scheme, for example:

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if ([request.URL.scheme isEqualToString:@"divupdated"]) { [self fieldUpdated]; return NO; } return YES; } 

and run something like this in webView:

 [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('myEditableDiv').addEventListener('change', function () {" @"var frame = document.createElement('iframe');" @"frame.src = 'divupdated://something';" @"document.body.appendChild(frame);" @"setTimeout(function () { document.body.removeChild(frame); }, 0);" @"}, false);"]; 
+7
source

You need to make some kind of JS hack for it to work.

First, create a JS file with a script that will add an observer that will watch all the editable separators when they start editing (I donโ€™t know exactly how this should be done in JS, but a quick Google search should help). The callback should then call a specially crafted URL, for example:

 textFieldBeginEditing://whateveryoulike 

Insert the JS file into the UIWebView. One possible way:

 - (void)injectJavascript:(NSString *)resource { NSString *jsPath = [[NSBundle mainBundle] pathForResource:resource ofType:@"js"]; NSString *js = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:NULL]; [self.webView stringByEvaluatingJavaScriptFromString:js]; } 

take another stream .

Finally, in the UIWebViewDelegate method shouldStartLoadingRequest

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // ... check the url schema NSURL *url = request.URL; if ([url.scheme isEqual:@"textFieldBeginEditing"]){ // here you can handle the event return NO; // important } } 
+1
source

All Articles