当使用具有可编辑内容的UIWebView
时,用户可以在可编辑的DIV上键入自己的文本。
有没有办法在每次用户更改可编辑文本时在 ViewController 上触发事件(类似于the UITextField
值更改事件)?
ViewController 需要知道用户何时更改了文本,原因有两个:了解用户是否输入了任何文本,以及随着内容文本的增长调整 UIWebView 的大小。
UIWebView
代表似乎不包括此类事件。这可能必须通过Javascript完成,但似乎找不到答案。帮助!
没有直接的方法可以从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);"];
你需要做一些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];
}
取自另一个 SO 线程。
最后,在UIWebViewDelegate方法应该StartLoadRequest
- (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
}
}