最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - shouldStartLoadWithRequest is not called in my iPhone App - Stack Overflow

programmeradmin1浏览0评论

I have a view controller with a UIWebView controller. I'm trying to get the javascript inside the html content of the web view to pass some information to my objective c code. I came across a number of examples online that set window.location in a javascript function and then catch the event generated by setting the view controller to be the web view's delegate and catching it in the shouldStartLoadWithRequest function. Unfortunately I can't get it to work because for me shouldStartLoadWithRequest is never called even though I'm setting the web view's delegate.

My code is as follows:

The interface:

@interface StoryTextViewController : UIViewController <UIWebViewDelegate>
{
    IBOutlet UIWebView *storyWebView;   
    NSString *information;
}

@property (nonatomic, retain) IBOutlet UIWebView *storyWebView;
@property (nonatomic, retain) NSString *information;

@end

In the interface, the *information variable is set by the previous view that calls StoryTextViewController.

The implementation:

#import "StoryTextViewController.h"

@implementation StoryTextViewController

@synthesize storyWebView;
@synthesize information;

- (NSString *) contructHTMLText
{
    NSString *HTMLText = @"";

    NSArray *words = [information ponentsSeparatedByString:@" "];
    NSString *header =
    @"<html>\n"
    "<head>\n"
    "<script type=\"text/javascript\">\n"

    "function marktext(theSpanID)\n"
    "{\n"
    "   var theSpan=document.getElementById(theSpanID);\n"
    "   if (theSpan.className == \"noHilite\")\n"
    "   {\n"
    "       theSpan.className = \"hilite\";\n"
    "       window.location = \"true\";\n"
    "   }\n"
    "   else\n"
    "   {\n"
    "       theSpan.className = \"noHilite\";\n"
    "       window.location = \"false\";\n"
    "   }\n"
    "}\n"

    "</script>\n"

    "<style type=\"text/css\">\n"

    ".hilite\n"
    "{\n"
    "   background-color:red;\n"
    "   color:white;\n"
    "   font: bold 60px arial,sans-serif\n"
    "}\n"

    ".noHilite\n"
    "{\n"
    "   background-color:white;\n"
    "   color:black;\n"
    "   font: 60px arial,sans-serif\n"
    "}\n"

    "</style>\n"

    "</head>\n"
    "<body>\n"
    "<div class=\"storyText\">\n";

    NSString *tailer = 
    @"</div>\n"
    "</body>\n"
    "</html>\n";

    HTMLText = [HTMLText stringByAppendingString:header];
    for (NSInteger i = 0; i < [words count]; i ++)
    {
        NSString *tag = [NSString stringWithFormat:@"   <span id=\"mytext%d\" class=\"noHilite\" onclick=\"marktext(\'mytext%d\')\">%@</span>&nbsp;\n", i, i, (NSString *)[words objectAtIndex:i]];
        HTMLText = [HTMLText stringByAppendingString:tag];
    }
    HTMLText = [HTMLText stringByAppendingString:tailer];
    NSLog(HTMLText);
    return HTMLText;
}

// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        storyWebView.delegate = self;
    }
    return self;
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *HTMLData = [self contructHTMLText];
    [storyWebView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: @""]];  
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

- (void)dealloc {
    [super dealloc];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{   
    // handle event here    
    return true;
}

@end

Whats happening is that basically, the constructHTML function takes the text inside the *information variable and wraps every word in the text with some html and javascript such that whenever a word is clicked, a css high-lighting is applied on it. What I want to do is to count the number of high-lighted words. I do this by trying to pass something in the function thats called whenever a word is clicked but like i said, the shouldStartLoadWithRequest method thats supposed to be fired is never executed.

I've seen a lot of people do this sort of thing but I cant seem to figure out why its not running for me

I have a view controller with a UIWebView controller. I'm trying to get the javascript inside the html content of the web view to pass some information to my objective c code. I came across a number of examples online that set window.location in a javascript function and then catch the event generated by setting the view controller to be the web view's delegate and catching it in the shouldStartLoadWithRequest function. Unfortunately I can't get it to work because for me shouldStartLoadWithRequest is never called even though I'm setting the web view's delegate.

My code is as follows:

The interface:

@interface StoryTextViewController : UIViewController <UIWebViewDelegate>
{
    IBOutlet UIWebView *storyWebView;   
    NSString *information;
}

@property (nonatomic, retain) IBOutlet UIWebView *storyWebView;
@property (nonatomic, retain) NSString *information;

@end

In the interface, the *information variable is set by the previous view that calls StoryTextViewController.

The implementation:

#import "StoryTextViewController.h"

@implementation StoryTextViewController

@synthesize storyWebView;
@synthesize information;

- (NSString *) contructHTMLText
{
    NSString *HTMLText = @"";

    NSArray *words = [information ponentsSeparatedByString:@" "];
    NSString *header =
    @"<html>\n"
    "<head>\n"
    "<script type=\"text/javascript\">\n"

    "function marktext(theSpanID)\n"
    "{\n"
    "   var theSpan=document.getElementById(theSpanID);\n"
    "   if (theSpan.className == \"noHilite\")\n"
    "   {\n"
    "       theSpan.className = \"hilite\";\n"
    "       window.location = \"true\";\n"
    "   }\n"
    "   else\n"
    "   {\n"
    "       theSpan.className = \"noHilite\";\n"
    "       window.location = \"false\";\n"
    "   }\n"
    "}\n"

    "</script>\n"

    "<style type=\"text/css\">\n"

    ".hilite\n"
    "{\n"
    "   background-color:red;\n"
    "   color:white;\n"
    "   font: bold 60px arial,sans-serif\n"
    "}\n"

    ".noHilite\n"
    "{\n"
    "   background-color:white;\n"
    "   color:black;\n"
    "   font: 60px arial,sans-serif\n"
    "}\n"

    "</style>\n"

    "</head>\n"
    "<body>\n"
    "<div class=\"storyText\">\n";

    NSString *tailer = 
    @"</div>\n"
    "</body>\n"
    "</html>\n";

    HTMLText = [HTMLText stringByAppendingString:header];
    for (NSInteger i = 0; i < [words count]; i ++)
    {
        NSString *tag = [NSString stringWithFormat:@"   <span id=\"mytext%d\" class=\"noHilite\" onclick=\"marktext(\'mytext%d\')\">%@</span>&nbsp;\n", i, i, (NSString *)[words objectAtIndex:i]];
        HTMLText = [HTMLText stringByAppendingString:tag];
    }
    HTMLText = [HTMLText stringByAppendingString:tailer];
    NSLog(HTMLText);
    return HTMLText;
}

// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        storyWebView.delegate = self;
    }
    return self;
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *HTMLData = [self contructHTMLText];
    [storyWebView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: @""]];  
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

- (void)dealloc {
    [super dealloc];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{   
    // handle event here    
    return true;
}

@end

Whats happening is that basically, the constructHTML function takes the text inside the *information variable and wraps every word in the text with some html and javascript such that whenever a word is clicked, a css high-lighting is applied on it. What I want to do is to count the number of high-lighted words. I do this by trying to pass something in the function thats called whenever a word is clicked but like i said, the shouldStartLoadWithRequest method thats supposed to be fired is never executed.

I've seen a lot of people do this sort of thing but I cant seem to figure out why its not running for me

Share Improve this question asked Jul 2, 2009 at 20:47 FahdFahd
Add a ment  | 

4 Answers 4

Reset to default 4

You can put breakpoint on setting delegate

if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    storyWebView.delegate = self;
}

I'm pretty sure storyWebView is nil on that moment.

You can fix it in this manner:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *HTMLData = [self contructHTMLText];
    // empty statement
    // the trick is that if the view is not loaded from the .nib yet
    // it will be loaded and all connections established

    if (self.view);

    // here is setting delegate
    storyWebView.delegate = self;
    [storyWebView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: @""]];  
}

You should set the delegate in viewDidLoad, not in initWithNibName:bundle:. Alternatively, open up your nib file and control-drag from the web view to your File's Owner, and choose "delegate" from the drop down.

  • Shouldn't window.location be the value of the target URL you are going to? In your marktext function you're setting it to true or false. shouldStartLoadWithRequest gets called only when a URL request has been received and is about to go somewhere. Not sure setting the location to a boolean is enough to trigger a navigation event. You can set it to a magic URL then return FALSE from the shouldStartLoadWithRequest routine if it's asking to navigate to that specific magic URL and prevent it from actually going somewhere. Valid URLs can then be allowed to go through.

  • Also might want to take a look at the response to this SO question. There may be some timing issues with window.location.

I also see this problem, because I have set the

articleWeb.userInteractionEnabled = NO;`

you'd better check your code, set

articleWeb.userInteractionEnabled = YES;`
发布评论

评论列表(0)

  1. 暂无评论