我正在使用 uiwebview 中加载的内容可编辑 html。我需要代码来设置键盘隐藏/显示时的光标位置

Posted

技术标签:

【中文标题】我正在使用 uiwebview 中加载的内容可编辑 html。我需要代码来设置键盘隐藏/显示时的光标位置【英文标题】:I am using content editable html loaded in uiwebview. I need the code to set the cursor position when the keyboard is hidden/shown 【发布时间】:2012-12-01 18:56:44 【问题描述】:

目前,当我点击 webview 时,键盘会出现,但内容会隐藏在键盘后面。当我一直按返回键时,也会发生同样的情况,光标/文本会出现在 webview 后面或不可见。

首先,我需要 iPad Evernote 应用程序中使用的功能。你可以看到光标永远不会在键盘后面,它总是从键盘上方开始。

【问题讨论】:

【参考方案1】:

我为此使用了 javascript。我正在使用一个类来使代码更有条理(因此您会在代码中看到一些this),但这不是必需的。

// this is used to get the current coordinates of the selection - not very efficient, so it shouldn't be called too often
this.updateOffset = function() 
  try
    var sel = window.getSelection();
    range = sel.getRangeAt(0);
    if(this.tmpSpan==null)
      this.tmpSpan = document.createElement('span');
    
    range.insertNode(this.tmpSpan);
    this.yOffset = this.tmpSpan.offsetTop;
    this.xOffset = this.tmpSpan.offsetLeft;
    this.tmpSpan.parentNode.removeChild(this.tmpSpan);
  
  catch(exc)
    log('updateOffset:' + exc.toString());
  


// eContent is the div with 'contenteditable', while visibleHeight is an int, set from objective-c (depending on where the webview is positioned, keyboard height and screen height)
this.scrollToVisible = function()
  try 
    if(this.eContent.clientHeight>this.visibleHeight)
      this.updateOffset();
      if(this.yOffset<window.pageYOffset)
        window.scrollTo(0, this.yOffset);
      
      else if(this.yOffset-window.pageYOffset>this.visibleHeight)
        window.scrollTo(0, this.yOffset-this.visibleHeight);
      
    
  
  catch (exc)
    log('scrollToVisible: ', exc.toString());
  

在objective-c中,我在键盘显示期间设置visibleHeight,然后在键盘显示完成后调用scrollToVisible

-(void)setVisibleHeight:(int)height
    [self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"docState.visibleHeight=%d", height]];

-(void)scrollToVisible
    [self stringByEvaluatingJavaScriptFromString:@"docState.scrollToVisible()"];

scrollToVisible 还会在 javascript 事件上调用:onkeyup、onpaset、oncut,它修复了按下“返回”或换行时的问题。

如果您决定采用这种方式,则在滚动浏览 javascript 时需要非常小心,否则可能会导致 UIWebview 控件出现一些问题(例如:将光标放在错误的位置,自动将光标移动到文档顶部等)

编辑 关于visibleHeight 的一些说明。据我所知,我之所以使用它是因为我无法从 javascript 中获取实际可见高度(document.body.clientHeight 还包括键盘后面的区域)。

由于我正在全屏显示UIWebView,因此我将可见高度设置如下:

- (void)keyboardWillShow:(NSNotification *)notification 
    ...
    NSDictionary *userInfo = [notification userInfo];
    NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardRect = [aValue CGRectValue];
    CGRect kbRect = [self.window convertRect:keyboardRect fromView:nil];
    _kbRect = kbRect;

    CGPoint sorigin = [self.superview convertPoint:self.frame.origin toView:nil];
    int visibleHeight = _kbRect.origin.y-sorigin.y-_tlbInputAccessory.frame.size.height-lkPadBottom; // _tlbInputAccessory is a custom accessory view
    [self stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"docState.setVisibleHeight(%d)", height]];
    ...

请注意,我是从UIWebView 的子类调用它,所以self 将代表UIWebView 控件。

【讨论】:

如何调用 -(void)setVisibleHeight:(int)height 我的意思是高度是多少? @MoorthyTheBoss 请参阅编辑以获取有关visibleHeight 的更多信息。 谢谢你能告诉我什么是lkPadBottom对象吗? 实际上我想在按下返回按钮时移动光标,就像 Evernote 应用程序一样我希望这个问题也和我的需要一样。我认为你的代码在键盘弹出时使光标位于键盘上方。 @MoorthyTheBoss lkPadBottom 是一个常数,在我的情况下它设置为 20。我不知道它在 Evernote 中是如何工作的,但这段代码用于将光标保持在键盘上方(默认情况下,它在某些情况下会隐藏在它后面)。对于选择或文本更改时的滚动,我使用 javascript 并在 onKeyUponPasteonCut 事件上手动处理滚动。

以上是关于我正在使用 uiwebview 中加载的内容可编辑 html。我需要代码来设置键盘隐藏/显示时的光标位置的主要内容,如果未能解决你的问题,请参考以下文章

在 UIWebView/WKWebview 中禁用自动完成

Xamarin iOS 在 UIWebView 中加载内容

在 UIWebview 中加载 Javascript+Html 内容

无法访问 iframe 中加载的自己域上的 httponly 标记 cookie

在 UITableViewCell 中加载 UIWebView 并根据 UIWebview 的内容制作 UITabViewCell 的高度

可编辑的 UIWebview 滚动问题