As a continuation of this post I wanted to share a few things about how I solved the problem of working w/ text in a UIWebView.
I did it mostly thru running Javascript via the stringByEvaluatingJavaScriptFromString: method on the UIWebView which I extended thru another class (e.g., MyWebView).
There’s a few key actions:
- override canPerformAction:withSender: to prevent the built-in menu
- create the JavaScript to get aspects of the selection in the web view
- run the JavaScript to get the info into your app
1. override canPerformAction:withSender: to prevent the built-in menu
Also, I override the canPerformAction:withSender: method to avoid the Copy/Cut/Paste menu from popping up. This is called when the user holds their finger down to select text in a webview. This gives you two things: 1. the chance to prevent the Copy/Cut/Paste menu and 2. it’s the notification that they are selecting text.
So how do you get what they selected?
2. create the JavaScript to get aspects of the selection in the web view
I saved my Javascript in separate files so I can read in the text and run it in the method (mentioned above). The following Javascript returns what is selected…
function f() {
var txt = window.getSelection();
return (txt.anchorOffset + '|' + txt.anchorNode.textContent + '|' + txt.focusOffset + '|' + txt.focusNode.textContent);
}
f();
The values are:
- txt.anchorOffset – the offset, in characters, where the selection begins
- txt.anchorNode.textContent – the text of that node (e.g., paragraph based on <p>)
- txt.focusOffset – the offset, in characters, where the selection ends
- txt.focusNode.TextContent – the text of that node
B/c the selection may go across nodes (e.g., selection starts in one paragraph and into another), you use anchor and focus objects.
From this you can determine what text is selected IF you also have the content the webview is rendering (the html or whatever). And based on that, you can insert font or style tags to alter the text (e.g., highlight, bold, etc.). If you don’t have the content, you can still get what they are selecting, but you probably can’t do anything w/ it in the web view.
3. run the JavaScript to get the info into your app
I store the above JavaScript in a file called getSelection.txt in the project. To run it, I have the following method…
-(NSString*)webviewGetSelection
{
NSString *js = [UtilString contentsOfFile:@"getSelection" withExt:@"txt"];
NSString *result = [self stringByEvaluatingJavaScriptFromString:js];
NSLog(@"selected: %@", result);
return result;
}
You as a result you might get:
0|Here is a paragraph.|3|Here is a paragraph.
This means they selected the 0-3 characters of that paragraph which works out to be the word: Here.
Another example result might be:
4|The middle word.|3|The first word.
This means the 4th character of the paragraph comprised of ‘The middle word.’ thru the 3rd character of the paragraph comprised of ‘The first word.’
This works out to be that they selected ‘middle word. The’
However, there may be a paragraph between those two paragraphs. If so, that entire paragraph is included in the selection.
If you have the content of the web view, you can search for the first paragraph and the second and get everything btwn them too. Otherwise, you’ll need to get more into the anchorNode/focusNode and/or create JavaScript to count the parentNodes and such to determine where the text is.
Some other useful Javascript methods are:
- self.find(<string>); – navigates to the next occurrence of a string
- window.pageYOffset; – basically tells you the scroll position of the webview
- window.scrollTo(x, y); – allows you to effectively set the scroll position
I hope this helps. Feel free to comment/improve/etc.




[...] UPDATE: I posted details on how I did it here. [...]
By: Detecting taps and events on UIWebView « Brainwash Inc. – iPhone/Mobile Development on February 10, 2010
at 17:19
Thank you for sharing. I think it very useful.
By: Phinh on March 8, 2010
at 02:21
Would you mind sharing some sample code which gets the selected text on UIWebView? Your suggestions are great, but I can’t accomplish them. I am at the point of being able to detect touch inside UIWebView (i used a link u provided) but stuck with getting the selected text. Thank you.
By: Cezar on March 11, 2010
at 08:44
Updated w/ more details and examples.
By: bearc0025 on March 11, 2010
at 10:51
Very nice. One question. It appears that the copy: selector is never called, so I can’t suppress the Copy popover menu. Did you find a way to do that? Did the SDK change since this post in Feb.?
I see there is a css style, -webkit-touch-callout: “none” — is that required, and if so, won’t that disable the text selection as well?
Would love some help if there is help to be had.
By: David Swanson on June 9, 2010
at 17:29
You need to override the canPerformAction:withSender: method to prevent the menu from popping up.
I don’t recall using the webkit-touch-callout: so I don’t think that’s necessary, but that might lead to a better solution than mine???
By: bearc0025 on June 10, 2010
at 11:16
@David Swanson:
Did you solve that problem by any chance? I’m encountering the same thing. For some reason I can’t suppress the Copy-menuItem.
By: Marc Köhlbrugge on July 12, 2010
at 17:01
I don’t recall having that problem and I haven’t looked at the code in a while. Let me check… looks like I just remove the menu as soon as the canPerformAction:withSender: method is called…
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { [UIMenuController sharedMenuController].menuVisible = NO; return NO; }By: bearc0025 on July 12, 2010
at 17:22
I’m actually adding another menu-item so that won’t work for me, unfortunately.
By: Marc Köhlbrugge on July 12, 2010
at 17:47
After disable the UIMenuController and calling the javascript to get the selected text …..I want to implement a custom UIMenucontroller with custom UIMenu.
Can you give me some kind of suggestions……
By: Anupam on June 2, 2011
at 06:01
I’m not sure, but maybe another reader can help???
By: bearc0025 on June 2, 2011
at 06:53
I want to allow user to highlight the text which he can see when he come back to same page
By: Soniya on February 27, 2012
at 23:29
You should be able to store the results and the url of the page to re-highlight later.
By: bearc0025 on February 28, 2012
at 09:26
I understand the fact that you are getting the selected text by running the JS. However, how do I highlight the selected text?
By: Azeem Shaikh on May 26, 2012
at 13:44
Since you have the selected text, you can programmatically change the html content to include font/style tags at the beginning and end of the selected text. Use those tags to highlight or otherwise modify the display of the text.
By: bearc0025 on May 28, 2012
at 12:43