Reputation: 4712
I have simple UIWebView
with loaded html file. I want to show the PopOverController
pointed to the selected text like -
.
I want the coordinates
of selected text from UIWebView
.
If I set the scalesPageToFit
property of UIWebView
to NO
, then this link works fine. If I set the scalesPageToFit
property of UIWebView
to YES
, then it fails.
Anyone please help me to sort out my problem.
Upvotes: 8
Views: 2515
Reputation: 5290
This must be be accomplished almost completely within JavaScript and then have the result passed back into Objective C. If you have control of the content you are showing, you can add this function into a <script>
tag. Otherwise you will need to inject it as described in this post.
function rectsForSelection() {
var i = 0, j = 0;
var allSelections = window.getSelection();
var result = []; // An empty array right now
// Generally, there is only one selection, but the spec allows multiple
for (i=0; i < allSelections.rangeCount; i++) {
var aRange = allSelections.getRangeAt(i);
var rects = aRange.getClientRects();
for (j=0; j<rects.length; j++) {
result.push(rects[j]);
}
}
return JSON.stringify(result);
}
Then from your Objective C code, you use do something like this:
NSString *rectsString = [webView stringByEvaluatingJavaScriptFromString:@"rectsForSelection();"];
NSData *rectsData = [rectsString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *rects = [NSJSONSerialization JSONObjectWithData:rectsData
options:0
error:NULL]; //Do Your Own Error Checking
I'll add that this will get coordinates that are valid within your webView.scrollView
, not your webView
.
Upvotes: 1
Reputation: 3437
UIWebView actually renders the HTML into UIViews, specifically it will probably render the selectable text into UITextView, so what you have to do is try to tap into the right view's delegate methods.
Here's a hack that should work:
UITextViewDelegate
method textViewDidChangeSelection:
to get the selectedRange and interact with it.** An alternative to step 3 and 4 is to use KVO to listen to changes in the textView's selectedRange.
Upvotes: 0
Reputation: 6079
have you tried that?
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(getCoordinates:)];
// [longPress setMinimumPressDuration:1];
[yourWebView addGestureRecognizer:longPress];
- (void)getCoordinates:(UILongPressGestureRecognizer *)sender {
CGPoint location = [sender locationInView:self.view];
NSLog(@"Tap at %1.0f, %1.0f", location.x, location.y);
}
Upvotes: 0
Reputation: 4325
First of all remove the native long press gesture recogniser like this:
for(UIGestureRecognizer *gesRecog in yourWebView.gestureRecognizers)
{
if([gesRecog isKindOfClass:[UILongPressGestureRecognizer class]])
{
[startTF removeGestureRecognizer:gesRecog];
}
}
Then assign a custom one:
UILongPressGestureRecognizer *myOwnLongPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleWebViewLongpress:)];
// set numberOfTapsRequired and numberOfTouchesRequired as per your requirement:
[yourWebView addGestureRecognizer:myOwnLongPressRecog];
// Handle Long press like this:
- (void) handleWebViewLongpress: (UIGestureRecognizer *) recog
{
int zoomedWidth = [[yourWebView stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] intValue];
CGFloat scale = yourWebView.frame.size.width / zoomedWidth; // get the scaled value of your web view
CGPoint zoomedCords = [gesture locationInView:self.webView];
zoomedCords.x /= scale; // Normal math. Divide by the scale to get the real thing.
zoomedCords.y /= scale;
NSLog(@"%@", zoomedCords);
}
Upvotes: 1