您的位置:首页 > 移动开发

UIWebview文字选中高亮

2014-09-21 18:28 162 查看
原文1:http://zframework.ph/how-to-search-a-string-inside-uiwebview/

原文2:http://zframework.ph/how-to-mark-or-get-the-highlighted-string-ins/


How To Search And Highlight A String Inside UIWebView

October
18, 2011 11:31 am | 1
Comment | Zaldy

UIWebView displays contents as a normal websites do but it doesn’t allow us to access its contents directly. So we have to use JAVASCRIPT in order to do that.

UIWebView has a method that can access any javascript implementations within your UIWebView (stringByEvaluatingJavaScriptFromString).

Since we need to use a Javascript, we need to add a javascript file to do this task. Download the javascript and html file here.
Extract the zip file once you finished downloading it.

You’ll see a javascript file (UIWebViewSearch.js) and html file (index.html)
there.

What
are these files anyway?

Start with the javascript file
(UIWebViewSearch.js).

This javascript file consist of a variable to count the number of result a string is found.

var uiWebview_SearchResultCount =
0;

And functions to highlight a string and removing all string highlights.

function uiWebview_HighlightAllOccurencesOfStringForElement(element,keyword) –
Search a string inside the HTML element.

function uiWebview_HighlightAllOccurencesOfString(keyword) - Highlight
all string occurences inside all elements of HTML file.

function uiWebview_RemoveAllHighlightsForElement(element)- Remove all
string highlights inside an elements of HTML file.

function uiWebview_RemoveAllHighlights()- Remove all string highlights
inside all elements of HTML file.

The HTML file index.html, had a sample web content there to try on searching
strings within our UIWebView.

Let’s
Do This!

This tutorial project is using a UISearchBar for string input and UIWebView to
display web contents. Let’s do this.

1. Create an XCode project named (WebViewStringSearch) as a single view
applciation or view based application if your using the older XCode IDE.

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)/…/UIWebViewSearch.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 UIWebViewSearch.js by
selecting it and click the minus (-) button.

Add UIWebViewSearch.js to the COPY BUNDLE RESOURCES by clicking the plus
(+) button and select the javascript 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 <UISearchBarDelegate>{
    UIWebView *_webView;
}

 

@property(nonatomic, retain) IBOutlet
UIWebView *webView;

 

- (NSInteger)highlightAllOccurencesOfString:(NSString*)str;
- (void)removeAllHighlights;

 

@end

We have a UISearchBar delegate there to enable search bar delegate methods.

We also have a variable _webView as outlet reference of UIWebView that you will add to your XIB file later on and declare it as property.

We also have two methods here used to highlight and remove the highlight of string.

5. Update your @implementation file (ViewController.m).

@synthesize webView = _webView;

Add this method:

/*
 Search A string inside UIWebView
with the use of the javascript function
 */
- (NSInteger)highlightAllOccurencesOfString:(NSString*)str
{
    // The JS File   
    NSString *filePath  = [[NSBundle
mainBundle] pathForResource:@”UIWebViewSearch” ofType:@”js” inDirectory:@”"];
    NSData *fileData    = [NSData
dataWithContentsOfFile:filePath];
    NSString *jsString  = [[NSMutableString
alloc] initWithData:fileData encoding:NSUTF8StringEncoding];
    [_webView stringByEvaluatingJavaScriptFromString:jsString];
    [jsString release];

    // The JS Function
    NSString *startSearch   = [NSString
stringWithFormat:@"uiWebview_HighlightAllOccurencesOfString('%@')",str];
    [_webView stringByEvaluatingJavaScriptFromString:startSearch];

    // Search Occurence Count
    // uiWebview_SearchResultCount
– is a javascript var
    NSString *result        = [_webView
stringByEvaluatingJavaScriptFromString:@"uiWebview_SearchResultCount"];
    return [result integerValue];
}

Above code will call the javascript file and execute the function to highlight a string inside webview web content.

Add this method:

/*
 Removes all highlighted string searched
before
 */
- (void)removeAllHighlights
{
    // calls the javascript function
to remove html highlights
    [_webView stringByEvaluatingJavaScriptFromString:@"uiWebview_RemoveAllHighlights()"];
}

Above code will call the javascript function to remove string highlights.

Add add this search bar delegate method:

#pragma mark – UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar
*)searchBar {

 

    [self removeAllHighlights];

    int resultCount = [self highlightAllOccurencesOfString:searchBar.text];

 

    // If no occurences of string,
show alert message
    if (resultCount <= 0) {
        UIAlertView *alert = [[UIAlertView
alloc] initWithTitle:@”Hey!” 
                                                       
message:[NSString stringWithFormat:@"No results found for string: %@", searchBar.text]
                                                      
delegate:nil 
                                             
cancelButtonTitle:@”Ok” 
                                             
otherButtonTitles:nil];
        [alert show];
        [alert release];
    }

    // remove kkeyboard
    [searchBar resignFirstResponder];
}

Above code is called when you tap the SEARCH button in the keyboard popup of UISearchBar. Then we remove highlights first before highlighting all string occurences and check if there are any occurences, if not then display an alert and remove the keyboard.

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 release];
    _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];
}

Above code will load the HTML file index.html file to our webview by the
time our view is loaded.

6. Now, add the UIWebView and UISearchBar components to your XIB file (ViewController.XIB). Then link UIWebView outlet and UISearchBar delegate to its owner. See screen-shot below.

link UIWebView outlet reference:





Links UISearchBar delegate to owner:





Compile
and Run!

Go ahead, compile and run. You should see something like this:



The
Code Please!

You can download the full source code here.

Posted
in: Tutorials


How To Mark Or Get The Highlighted String Inside UIWebView

November
4, 2011 5:48 am | 11
Comments | Zaldy

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,4characters,
a total of 5 characters. 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.

We also have a function to remove all highlights. This function is also used on my previous post to mark/highlight a searched string.

// 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 andRemove
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.

Posted
in: Tutorials
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: