Как я могу открывать новые страницы в новых UIWebViews?

#ios #objective-c #uiwebview

#iOS #objective-c #uiwebview

Вопрос:

Я хотел бы открывать новые веб-страницы в new UIWebViews . Например, когда вы заходите в Google, это будет считаться одной веб-страницей, но когда вы нажимаете на Google Images в Google, это будет считаться новой веб-страницей.

Все новые веб-страницы будут загружены в new UIWebViews и будут помещены в массив истории, содержащий все UIWebViews .

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if (navigationType == UIWebViewNavigationTypeBackForward) {

        // The UIWebView already exists for that page in the history array, call it and display it.
    }
    else if (navigationType == UIWebViewNavigationTypeFormResubmitted) {

        // No problem, load it in the current UIWebView.
    }
    else if (navigationType == UIWebViewNavigationTypeFormSubmitted) {

        // It's a new page, load it in a new UIWebView.
    }
    else if (navigationType == UIWebViewNavigationTypeLinkClicked) {

        // It's a new page, load it in a new UIWebView
    }
    else if (navigationType == UIWebViewNavigationTypeReload) {

        // Just reload the current UIWebView.
    }
    else if (navigationType == UIWebViewNavigationTypeOther) {

        // There's no way this is a new page. Do nothing.
    }
}
  

Как вы, наверное, уже догадались, это не сработало. Все, что вам нужно сделать, это следовать по этому пути:

  1. Перейдите к http://www.9gag.com
  2. Нажмите значок «Поделиться в твиттере» под любым сообщением.

Ссылка для публикации в Twitter будет выглядеть примерно так:

 https://twitter.com/intent/tweet?original_referer=http://9gag.com/gag/aRQpqj2?ref=t.mwamp;source=tweetbuttonamp;text=I don't throw the word 'genius' around loosely, but...amp;url=http://9gag.com/gag/aRQpqj2?ref=t.mwamp;via=9GAG
  

Хотя кто-то может ожидать, что эта ссылка будет типа LinkClicked, потому что вы нажали на значок Twitter, чтобы перейти туда, на самом деле это тип Other, любой настольный веб-браузер сочтет эту ссылку всплывающим окном и открыл бы ее в новом окне. Safari на iOS открывает эту ссылку на новой вкладке. Я хотел бы открыть его в новом UIWebView , но проблема в том, что нет ничего, что отличало бы рекламный запрос от всплывающего запроса в UIWebView делегате.

Как Safari это делает?

РЕДАКТИРОВАТЬ: ответ ниже — это именно проблема UIWebView . Это вводит всех в заблуждение, заставляя думать, что делегат — это ответ, когда на самом деле вы ничего не можете сделать, не взломав свой путь, даже самые простые вещи.

РЕДАКТИРОВАТЬ 2: я проверил и другие браузеры, такие как Mercury, и они поняли это правильно. Они понимают, что Twitter — это всплывающее окно, и открывают его на новой вкладке. Итак, это не вина Apple.

Комментарии:

1. Это может привести к очень высокому использованию памяти и, скорее всего, вызовет некоторые предупреждения о памяти, если у вас сразу загружается UIWebView s. Действительно ли это лучший способ сделать это?

2. Короткий ответ: да, это возможно с небольшим управлением памятью, но я бы предпочел не спорить об этом.

3. Это какой-то ад управления памятью, если вы создаете новое UIWebView для каждого UIWebViewNavigationTypeLinkClicked , у вас может быть сотни, я вижу, что Apple отклоняет это из-за проблем с памятью, честно говоря, я бы рекомендовал переосмыслить ваш дизайн здесь.

4. Серьезно, дюжина UIWebViews — это все, что мне нужно. 12 * 20 МБ = 240 МБ оперативной памяти. Вы должны верить в меня 🙂

5. Дюжина веб-просмотров все равно создаст проблемы. Попробуйте просто создать простой проект и просто добавьте 5 веб-просмотров, которые загружают Google, и увидите, как объем памяти взлетает до небес.

Ответ №1:

Установите делегат вашего первого веб-представления на свой контроллер представления. После этого добавьте следующий код в свой контроллер просмотра.

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"%@", request.URL);
    NSLog(@"%@", [request.URL scheme]);
    if ([[request.URL scheme] isEqualToString:@"http"])
    {
        // Create web view here, because you're catching all requests
        // Don't forget to set the delegate.
        NSLog(@"Create new web view with %@", request.URL);
        return NO;
    }

    return YES;
}
  

Как вы можете видеть, вы должны заменить ту часть, где я добавил NSLog. Вероятно, на этом этапе вам захочется создать новое веб-представление и добавить его в текущее представление в качестве вложенного представления.

Почему вы хотите проверить LinkClicked и не перехватывать все запросы?

Комментарии:

1. Не уверен, что это действительно помогает, это создало бы больше проблем с памятью, поскольку вы говорите, что создаете новый UIWebView для каждого запроса, а не только для UIWebViewNavigationTypeLinkClicked and UIWebViewNavigationTypeFormSubmitted . -1

2. Это действительно не помогает, и Popeye это не то, что я хочу делать. Позвольте мне объяснить, речь идет о новых страницах. Всплывающие страницы считаются новыми страницами, но их тип не UIWebViewNavigationTypeLinkClicked и не UIWebViewNavigationTypeFormSubmitted их тип (удивительно) uiwebviewnavigationtypeдругой, хотя вы нажали на ссылку. 🙁

3. Хорошо, мои извинения. Я думаю, тогда вы застряли с Apple. Именно так они реализовали UIWebView, и я не думаю, что есть какой-либо способ принудительно щелкнуть ссылку для всплывающих окон. Возможно, javascript открывает всплывающее окно, поэтому ссылка фактически не нажата.

4. Как я упоминал выше, я проверил другие сторонние браузеры, которые там не застревают.