#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.
}
}
Как вы, наверное, уже догадались, это не сработало. Все, что вам нужно сделать, это следовать по этому пути:
- Перейдите к http://www.9gag.com
- Нажмите значок «Поделиться в твиттере» под любым сообщением.
Ссылка для публикации в 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
andUIWebViewNavigationTypeFormSubmitted
. -12. Это действительно не помогает, и Popeye это не то, что я хочу делать. Позвольте мне объяснить, речь идет о новых страницах. Всплывающие страницы считаются новыми страницами, но их тип не UIWebViewNavigationTypeLinkClicked и не UIWebViewNavigationTypeFormSubmitted их тип (удивительно) uiwebviewnavigationtypeдругой, хотя вы нажали на ссылку. 🙁
3. Хорошо, мои извинения. Я думаю, тогда вы застряли с Apple. Именно так они реализовали UIWebView, и я не думаю, что есть какой-либо способ принудительно щелкнуть ссылку для всплывающих окон. Возможно, javascript открывает всплывающее окно, поэтому ссылка фактически не нажата.
4. Как я упоминал выше, я проверил другие сторонние браузеры, которые там не застревают.