使用带有可修改内容的UIWebView
时,用户可以在可编辑的DIV上键入自己的文字。
每次用户更改可编辑文本时,是否有办法在ViewController上触发事件(类似于the UITextField
值更改事件)?
ViewController需要知道用户何时更改为文本有两个原因;了解用户是否输入了任何文本,并在内容文本增长时调整UIWebView的大小。
UIWebView
委托似乎不包含此类事件。这可能必须通过Javascript完成,但似乎无法找到答案。救命啊!
答案 0 :(得分:8)
没有直接的方法来侦听UIWebView中的事件,但您可以桥接它们。从iOS7开始,它很容易,因为有JavaScriptCore.framework(你需要将它与项目链接):
JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"myUpdateCallback"] = ^(JSValue *msg) {
[self fieldUpdated];
};
[ctx evaluateScript:@"document.getElementById('myEditableDiv').addEventListener('input', myUpdateCallback, false);"];
(目前我没有可能测试代码,但我希望它有效)
在iOS7之前(如果你想支持更低版本,你必须使用它),这有点棘手。您可以在webView委托方法webView:shouldStartLoadWithRequest:navigationType:
上侦听某些自定义方案,例如:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([request.URL.scheme isEqualToString:@"divupdated"]) {
[self fieldUpdated];
return NO;
}
return YES;
}
并在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);"];
答案 1 :(得分:1)
你需要做一些JS黑客才能实现这个目的。
首先,创建一个带有脚本的JS文件,该脚本添加一个观察者,观察他们开始编辑时所有可编辑的div(我不确切知道如何在JS中完成此操作,但快速搜索Google应该救命)。然后回调应该调用一个特制的URL,如:
textFieldBeginEditing://whateveryoulike
将JS文件注入UIWebView。一种可能的技术:
- (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];
}
最后,在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
}
}