Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting caret (cursor) vertical position in a UIWebView

In order to manage automatic scrolling in a content editable UIWebView, I need to get the correct caret Y vertical coordinate.

I identified two methods, using javascript.

The first one uses getClientRects javascript function:

    CGRect caretRect = [self.webView stringByEvaluatingJavaScriptFromString: @"
        var sel = document.getSelection();
        var range = sel.getRangeAt(0).cloneRange();
        range.collapse(true);
        var r =range.getClientRects()[0];
        return '{{'+r.left+','+r.top+'},{'+r.width+','+r.height+'}}';"];
    int caretY = caretRect.origin.y;

With this, the caret keeps blinking and one gets its correct vertical position with one problem: when user type return key, so that the next line is empty, caretY is equal to zero until a character key is typed. So that this method cannot be use.

The second one insert a tmp span, then removes it:

int caretY = [[self.webView stringByEvaluatingJavaScriptFromString: @"      
    var sel = window.getSelection(); 
    sel.collapseToStart();
    var range = sel.getRangeAt(0);
    var span = document.createElement(\"span\");
    range.insertNode(span); 
    var topPosition = span.offsetTop; 
    span.parentNode.removeChild(span); 
    topPosition;"] intValue];

This gives the correct caretY in any situation. But the caret stops blinking, which is very unhelpful to see it on the screen.

Does anybody knows any method (or adaptation of these) that can make the following:

    - get the correct caret Y in any situation
    - keep the caret blinking in any situation

Thanks

like image 547
Denis Avatar asked May 06 '14 09:05

Denis


1 Answers

Not sure if this is too late; the following works for me.

Add getCaretY() below to your js file:

function getCaretY() {
    var y = 0;
    var sel = window.getSelection();
    if (sel.rangeCount) {
        var range = sel.getRangeAt(0);
        if (range.getClientRects) {
            var rects = range.getClientRects();
            if (rects.length > 0) {
                y = rects[0].top;
            }
        }
    }
    return y;
}

Then call it from obj-c file as below:

NSString *yPos = [webView stringByEvaluatingJavaScriptFromString:@"getCaretY()"];
like image 55
defy Avatar answered Oct 31 '22 11:10

defy