shouldStartLoadWithRequest не вызывается в моем приложении для iPhone

У меня есть контроллер представления с контроллером UIWebView. Я пытаюсь получить javascript внутри html-содержимого веб-представления, чтобы передать некоторую информацию моему целевому коду c. Я столкнулся с рядом примеров в Интернете, которые устанавливают window.location в функции javascript, а затем перехватывают событие, сгенерированное путем установки контроллера представления в качестве делегата веб-представления и перехвата его в функции shouldStartLoadWithRequest. К сожалению, я не могу заставить его работать, потому что для меня shouldStartLoadWithRequest никогда не вызывается, даже если я устанавливаю делегат веб-представления.

Мой код выглядит следующим образом:

Интерфейс:

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

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

@end

В интерфейсе переменная *information задается предыдущим представлением, которое вызывает StoryTextViewController.

Реализация:

#import "StoryTextViewController.h"

@implementation StoryTextViewController

@synthesize storyWebView;
@synthesize information;

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

    NSArray *words = [information componentsSeparatedByString:@" "];
    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

Происходит то, что в основном функцияstructHTML берет текст внутри переменной *information и оборачивает каждое слово в тексте некоторым html и javascript, так что всякий раз, когда слово нажимается, к нему применяется подсветка css. Что я хочу сделать, так это подсчитать количество выделенных слов. Я делаю это, пытаясь передать что-то в функцию, которая вызывается всякий раз, когда щелкают слово, но, как я уже сказал, метод shouldStartLoadWithRequest, который должен запускаться, никогда не выполняется.

Я видел, как многие люди делают подобные вещи, но я не могу понять, почему это не работает для меня.


person Community    schedule 02.07.2009    source источник


Ответы (4)


Вы можете поставить точку останова при настройке делегата

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

Я почти уверен, что в этот момент storyWebView равен нулю.

Вы можете исправить это следующим образом:

- (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: @""]];  
}
person Valerii Hiora    schedule 03.07.2009
comment
Я сделал, как вы предложили, но это не имело никакого значения. self не был нулевым с самого начала. Можете еще что-нибудь предложить? - person ; 05.07.2009
comment
self наверняка не будет нулевым, а как насчет storyWebView? - person Valerii Hiora; 06.07.2009
comment
Неа. представление истории также отлично отображает html. я совсем запутался. если вы хотите, может быть, я могу отправить вам то, что я закодировал? мой босс становится немного нетерпеливым, и я впадаю в отчаяние - person ; 06.07.2009
comment
Вы можете отправить его. Использовать мое имя и второе имя в gmail, точка com - person Valerii Hiora; 07.07.2009
comment
Хорошо, настоящая причина проблемы в том, что вы загружаете HTML через loadHTMLString. - person Valerii Hiora; 07.07.2009
comment
какое решение для этого. У меня такая же проблема. И загрузка HTML через loadHTMLString - person robert; 12.07.2013

Вы должны установить делегата в viewDidLoad, а не в initWithNibName:bundle:. В качестве альтернативы откройте файл пера и перетащите его из веб-представления к владельцу файла и выберите «делегировать» в раскрывающемся списке.

person Frank Schmitt    schedule 22.12.2010

  • Разве window.location не должно быть значением целевого URL-адреса, на который вы собираетесь перейти? В вашей функции marktext вы устанавливаете ее на true или false. shouldStartLoadWithRequest вызывается только тогда, когда получен запрос URL и он собирается куда-то перейти. Не уверен, что установка логического значения местоположения достаточна для запуска события навигации. Вы можете установить магический URL-адрес, а затем вернуть FALSE из подпрограммы shouldStartLoadWithRequest, если она просит перейти к этому конкретному магическому URL-адресу и предотвратить его фактическое перемещение куда-либо. Действительные URL-адреса могут быть разрешены для прохождения.

  • Также, возможно, стоит взглянуть на ответ на этот вопрос SO . Могут быть некоторые проблемы с синхронизацией window.location.

person Ramin    schedule 02.07.2009
comment
На самом деле я пытаюсь установить для window.locaton строки true или false, но это не имеет значения, потому что мой код не работает ни для какой строки. Я также посмотрел ссылку, которую вы мне прислали, но это было не то, что мне было нужно. Его проблема в том, что shouldStartLoadWithRequest работает для него СЛИШКОМ хорошо, тогда как в моем случае он вообще не вызывается! - person ; 05.07.2009
comment
Не знаете, почему вы пытаетесь установить значение местоположения «истина» или «ложь»? Это похоже на ввод true в адресной строке. Что произойдет, если вы используете допустимый URL-адрес, например stackoverflow.com? Моя точка зрения заключалась в том, что я не думаю, что shouldStartLoadWithRequest вызывается, если вы не дадите ему действительный URL-адрес для перехода. - person Ramin; 06.07.2009

Я также вижу эту проблему, потому что я установил

articleWeb.userInteractionEnabled = NO;`

вам лучше проверить свой код, установить

articleWeb.userInteractionEnabled = YES;`
person Eric    schedule 23.11.2010