【获取、高亮UIWebView中选择的文本】How To Mark Or Get The Highlighted String Inside UIWebView
转自国外的一个网站,非常好的东西。国外的网址图片显示不全且不容易查看。加密问题。现在自己整理发上来以帮助网友和自己。
Before we go over with this tutorial, I would like to thank everyone for reading my posts, for asking questions and for giving suggestions. Because of that, I will continue writing tutorials that might help other developers get rid of headaches and frustrations.
This tutorial is a follow up tutorial from my previous post. Someone find it simple yet helpful and ohers have questions if it is possible to mark/stylize and get those strings inside UIWebView that are selected or highlighted. So I created this tutorial to support that question.
Let's get started!
Since we are still manipulating UIWebView, we need to gain access to its contents. In order to do this, we have to use Javascripts.
With Javascript, we can access UIWebViews contents like normal browsers do.
In this tutorial, we will use UIWebViews method (stringByEvaluatingJavaScriptFromString) to access javascript files and execute its functions.
Download the javascript and html file here. After downloading the zip file, extract the file and you should have two files (HighlightedString.js and index.html).
What are these files?
The html file (index.html) handles the UIWebView content.
That javascript file (HighlightedString.js) handles all the job of getting or marking highlighted strings inside UIWebView.
Inside that javascript file, we have variable to store the selected text.
var selectedText = "";
We also have a function to get the highlighted strings.
function getHighlightedString() { var text = window.getSelection(); selectedText = text.anchorNode.textContent.substr(text.anchorOffset, text.focusOffset - text.anchorOffset); }
This function above will access the window and perform the getSelection() operation to access of UIWebViews contents.
Then, we parse UIWebView's contents using the anchorOffset and focusOffset.
- anchorOffset() - returns the first index position of the highlighted strings. For example if my UIWebView has content "My name is Zaldy", and you highlighted Zaldy. You're anchorOffset is 11 which is the character "Z". Because it counts all characters from the beginning of the content as index 0.
- focusOffset() - returns the last index position of the highlighted strings. With the latter example, our focusOffset is 15 which refers to the last character of the highlighted string, the character "y".
Now, in order to acquire the highlighted strings, we parse the UIWebView contents and scan the content using the operation text.anchorNode.textContent.substr(int startingIndex, int length). This operation takes two paramters, the first one is the starting position of the character to parse, the second one is the length of the string to end the parsing.
So if our UIWebView has content "My name is Zaldy" and we have anchorOffset() = 11 with focusOffset() = 15. Our string length would be 15 - 11 = 4. Remember that 4 means we have 0,1,2,3,4 characters, a total of 5characters. The parser now scan's the content from index 11 with string length 4, so it will end scanning to character "y".
Hope that sounds clear to you guys.
Another function is to stylize/mark any highlighted string inside UIWebView content.
function stylizeHighlightedString() { var range = window.getSelection().getRangeAt(0); var selectionContents = range.extractContents(); var span = document.createElement("span"); span.appendChild(selectionContents); span.setAttribute("class","uiWebviewHighlight"); span.style.backgroundColor = "black"; span.style.color = "white"; range.insertNode(span); }
That function above captures the range of our selection and put a <span> element before the first character of the highlighted string and put the </span> after the last character of the highlighted string. After that, we add a class attribute named "uiWebviewHighlight" with defined style backgroundColor to black and font color style to white. Then insert the changes to the highlighted strings and update the UIWebView content.
Note: You can always change the colors of marker's background and text.
// helper function, recursively removes the highlights in elements and their childs function uiWebview_RemoveAllHighlightsForElement(element) { if (element) { if (element.nodeType == 1) { if (element.getAttribute("class") == "uiWebviewHighlight") { var text = element.removeChild(element.firstChild); element.parentNode.insertBefore(text,element); element.parentNode.removeChild(element); return true; } else { var normalize = false; for (var i=element.childNodes.length-1; i>=0; i--) { if (uiWebview_RemoveAllHighlightsForElement(element.childNodes[i])) { normalize = true; } } if (normalize) { element.normalize(); } } } } return false; }
That function above recursively removes all element occurence that has class attribute named "uiWebviewHighlight". This will remove all marks/highlights defined to that class attribute.
.Let's do this!
This tutorial project is using an iOS5 SDK with Storyboards and ARC.
1. Create an XCode project named (WebViewHighlight) as a single view applciation. Check the Use Of Storyboard and the Use of Automatic Reference Counting.
2. Add the javascript and html file to your XCode.
3. Note: once you have added a javascript file to your XCode. XCode will displays a warning:
warning: no rule to process file '$(PROJECT_DIR)/.../HighlightedString.js' of type sourcecode.javascript for architecture i386
This happens because it compiles a javascript file and will find it weird. So that our XCode will not compile our javascript file, go to your TARGET and select the BUILD PHASES tab and expand the COMPILE SOURCES then remove the HighlightedString.js by selecting it and click the minus (-) button.
Add HighlightedString.js to the COPY BUNDLE RESOURCES by clicking the plus (+) button and select the jabascript file. See below screen-shot.
Remove js file from Compile Sources.
Add js file to the Copy Bundle Resources.
This will add the javascript file to your project's bundle resources without compiling it.
4. Update your ViewController header file (ViewController.h) with the code below.
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @property(nonatomic, retain) IBOutlet UIWebView *webView; - (IBAction)removeAllHighlights; - (IBAction)markHighlightedString:(id)sender; - (IBAction)getHighlightedString:(id)sender; @end
We have an IBOutlet UIWebView variable and functions to mark, get and remove highlighted strings.
5. Update your @implementation file (ViewController.m).
Add these below @implementation.
{ UIWebView *_webView; } @synthesize webView = _webView;
Add this method.
- (IBAction)markHighlightedString:(id)sender { // The JS File NSString *filePath = [[NSBundle mainBundle] pathForResource:@"HighlightedString" ofType:@"js" inDirectory:@""]; NSData *fileData = [NSData dataWithContentsOfFile:filePath]; NSString *jsString = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; [_webView stringByEvaluatingJavaScriptFromString:jsString]; // The JS Function NSString *startSearch = [NSString stringWithFormat:@"stylizeHighlightedString()"]; [_webView stringByEvaluatingJavaScriptFromString:startSearch]; }
Above code will call the javascript file and execute the function to mark any highlighted strings inside your webview content.
Add this method.
- (IBAction)getHighlightedString:(id)sender { // The JS File NSString *filePath = [[NSBundle mainBundle] pathForResource:@"HighlightedString" ofType:@"js" inDirectory:@""]; NSData *fileData = [NSData dataWithContentsOfFile:filePath]; NSString *jsString = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding]; [_webView stringByEvaluatingJavaScriptFromString:jsString]; // The JS Function NSString *startSearch = [NSString stringWithFormat:@"getHighlightedString()"]; [_webView stringByEvaluatingJavaScriptFromString:startSearch]; NSString *selectedText = [NSString stringWithFormat:@"selectedText"]; NSString * highlightedString = [_webView stringByEvaluatingJavaScriptFromString:selectedText]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Highlighted String" message:highlightedString delegate:nil cancelButtonTitle:@"Oh Yeah" otherButtonTitles:nil]; [alert show]; //[alert release]; // not required anymore because of ARC }
Above code will call the javascript file and execute the function to get any highlighted strings inside webview content and push an alert view.
Add this method.
- (IBAction)removeAllHighlights { // calls the javascript function to remove html highlights [_webView stringByEvaluatingJavaScriptFromString:@"uiWebview_RemoveAllHighlights()"]; }
Above code will call the javascript function to remove string highlights.
Update your - (void)viewDidUnload with this code:
- (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; _webView = nil; }
Update your - (void)viewDidLoad with this code:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // Load index.html to our webview NSString *urlAddress = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; //you can also use PDF files NSURL *url = [NSURL fileURLWithPath:urlAddress]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; [_webView loadRequest:requestObj]; // Menu Controller UIMenuController *menuController = [UIMenuController sharedMenuController]; UIMenuItem *getHighlightString = [[UIMenuItem alloc] initWithTitle: @"Get String" action: @selector(getHighlightString:)]; UIMenuItem *markHighlightedString = [[UIMenuItem alloc] initWithTitle: @"Mark String" action: @selector(markHighlightedString:)]; [menuController setMenuItems: [NSArray arrayWithObjects:getHighlightString, markHighlightedString, nil]]; }
Above code will load the HTML file index.html file to our webview by the time our view is loaded. There is a UIMenuController object added there as well, which will add two popup menu options when you highlight a string inside UIWebView with targets pointing to our IBAction methods. See screenshot below.
Add this method.
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(getHighlightString:)) { return YES; } else if (action == @selector(markHighlightedString:)) { return YES; } return NO; }
Above code will disable other popup menu items and show our newly added popup menu items.
6. Now, add the UIWebView and UIButton components to your storyboard file (MainStoryboard.storyboard). Then link UIWebView outlet and UIButton actions . See screen-shot below.
link UIWebView outlet reference:
link UIButton action events (Do this also with the rest of the buttons Get Highlighted String and Remove Highlights to action events getHighlightedString: and removeAllHighlights)
:Compile and Run!
Go ahead, compile and run. You should see something like this:
Marking a highlighted string.
Get the highlighted string.
The Code Please!
You can download the full source code here.
原帖地址:https://zaldzbugz.posterous.com/how-to-mark-or-get-the-highlighted-string-ins