2016-01-09 5 views
9

В моем приложении iOS, написанном в Swift 2.1, я использую WKWebView для загрузки строки HTML, загружаемой из блога Wordpress с использованием анализатора JSON.Ссылки в WKWebView случайным образом не доступны для просмотра

Я реализовал метод делегата func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) { и назначил делегат навигации WKWebView себе, чтобы обрабатывать ссылки.

Теперь, когда я открываю ViewController, который содержит WKWebView, этот метод делегата вызывается один раз, что является поведением, которое вы ожидаете при загрузке webView, поэтому делегат, кажется, правильно настроен.

Моя проблема теперь в том, что в большинстве случаев ссылки, которые содержит webView, являются не доступны для скачивания. Обычно вы ожидаете, что появится серый фон, когда вы нажмете ссылку, как вы можете видеть на изображении ниже. Но в большинстве случаев, когда я нажимаю ссылку, серый фон не появляется, поэтому, когда я касаюсь, метод делегата не вызывается. Эта проблема, безусловно, не должна что-то делать с неправильной конфигурацией WKNavigationDelegate, так как иногда выбор ссылок работает правильно (около 10%).

appearance of links when you select them

Есть ли у вас какие-либо идеи, почему ссылки случайно иногда не кликабельны, а иногда и интерактивные (10% случаев)?


+0

Было бы хорошо, если бы вы могли бы показать нам свой HTML. – adrianokw

+1

Вы забыли «импортировать QuartzCore»? –

ответ

1

Решение состоит в том, чтобы удалить использование contentInset. К сожалению, WKWebView не предназначен для обработки использовать его (при contentInset отрицательна), поэтому мы должны использовать обходной путь, просто добавив пустой div в HTMLString, просто так:

<div style='width:100%;height:100px'></div> 

Если дно вставка должна быть изменена без перезагрузки всей страницы, сначала можно вставить огромный div внизу, а затем скомпенсировать ее добавлением положительного contentInset. Это именно то, что делает это расширение:

extension WKWebView { 

    /// The maximum possible height of the webView bottom content inset 
    @nonobjc static let maxBottomHeight: CGFloat = 20000 

    /// Provides an easy way to set the real bottom inset of the webView. Due to a bug in WKWebView framework, we first insert an emtpy div with the size WKWebView.maxContentSize on the bottom of the webView and compensate it by setting a positive contentInset (should be positive, otherwise the bug will be there again). 
    func set(bottomInset inset: CGFloat) { 

     self.scrollView.contentInset.bottom = inset - WKWebView.maxBottomHeight 
    } 
} 

Не забудьте добавить div в конце строки HTML:

let htmlFooter = "<div style='width:100%;height:\(String(describing: WKWebView.maxBottomHeight))px'></div></body></html>" 
1

при загрузке вашего контента в WKWebView, вы можете установить неправильно BaseUrl для вашей веб-страницы, и это приводит к недопустимой связи, для того, чтобы она работает правильно, вы должны иметь ваш BaseUrl настроен на правильный HTTP или https URL для вашего контента, для этой рабочей ссылки только потому, что у них есть полный URL-адрес в их href.

здесь HTML-текст нагрузки в WKWebView, чтобы проиллюстрировать эффект:

webView.loadHTMLString(content, baseURL: NSURL(string: "")); 

содержание:

<html lang="en"><head><meta name="viewport" content="width=device-width, initial-scale=1"></head> 
    <body> 
     <h1> click testing </h1> 
     <ul> 
      <li><a href="http://www.w3schools.com">Visit W3Schools</a></li> 
      <li><a href="/about">Un-Clickable without baseURL</a></li> 
      <li><a href="about://about">Clickable without baseURL</a></li> 
     </ul> 
    </body> 
</html> 
+1

К сожалению, это не решение моей проблемы, так как я загружаю html-строку в webView, а не на веб-сайт. – fredpi

+1

@returnfalse, конечно, я говорю о вашей строке html, это простой HTML-текст, вы не разделяете html? – Allen

+0

спасибо за ответ, но проблема здесь в том, что я не могу открывать ссылки случайно, поэтому иногда работает конкретная ссылка, а иногда и нет. Если это будет проблемой с baseURL, это всегда будет не кликабельным. – fredpi

1

Я собираюсь предположить, что то, что вы хотите иметь некоторое описание или текст в некоторых место и разрешить внутри некоторой части текста сделать clickable/tapped, и для этого вы хотите использовать WKWebView.

Я решил эту проблему, используя WKWebView тоже в некоторых приложениях, которые я сделал давно, конечно, есть несколько решений, это всего лишь один из них, ничего другого.

Как вам сказали некоторые люди, вы можете использовать функцию loadHTMLString для загрузки строки HTML с вашего сервера в JSON или в любом случае, но очень важно, чтобы HTML был хорошо отформатирован без ошибок.

Очень важный момент о функции loadHTMLString относительно вашего комментария ... Вы, как правило, ожидают, что аа серый фон появляется, когда пресс-ссылку, как вы можете видеть на изображении ниже, это не произойдет, если в HTML не имеют какого-то стиля CSS, потому что если он не имеет стиль по умолчанию для любого из <a><\a>.

Итак, давайте посмотрим на следующий код:

import UIKit 
import WebKit 

class ViewController: UIViewController, WKNavigationDelegate { 

    var wkWebView: WKWebView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // The part of the HTMl you want to show 
     let description = "Let's start to visit the <a href=\"http://www.apple.com/\">Apple</a> website first and then if you want the <a href=\"http://www.w3schools.com\">Developer Apple</a> website." 


     // The default HTML with body and styles formatted and the description inside using string interpolation. 
     let htmlString = "<html><head><style type=\"text/css\">body {font-family: \"Lato-Regular\";font-size: 35px;color: #333333;margin: 0;}a {text-decoration: none; color: #999;}</style></head><body>\(description)</body></html>" 

     let preferences = WKPreferences() 
     preferences.javaScriptEnabled = false 

     // Configuration for any preferences you want to set 
     let configuration = WKWebViewConfiguration() 
     configuration.preferences = preferences 

     wkWebView = WKWebView(frame: CGRectMake(5, 35, self.view.bounds.width, self.view.bounds.height), configuration: configuration) 

     if let theWebView = wkWebView { 
      theWebView.loadHTMLString(htmlString, baseURL: NSURL()) 
      theWebView.navigationDelegate = self 
      self.view.addSubview(theWebView) 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { 
     UIApplication.sharedApplication().networkActivityIndicatorVisible = true 
    } 


    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) { 
     UIApplication.sharedApplication().networkActivityIndicatorVisible = false 
    } 

    func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) { 
    let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .Alert) 
    alert.addAction(UIAlertAction(title: "Ok", style: .Default) { (UIAlertAction) -> Void in 
     UIApplication.sharedApplication().networkActivityIndicatorVisible = false 
    }) 

    presentViewController(alert, animated: true, completion: nil) 
    } 
} 

В приведенном выше коде я установил переменную description с текстом с интерактивными элементами внутри него и добавил двух методов делегат didStartProvisionalNavigation и didFinishNavigation показать в в networkActivityIndicatorVisible чтобы показать некоторый прогресс в загрузке страницы при нажатии на текст, который можно щелкнуть. Приятно заметить, что в переменной htmlString я установил некоторые стили, чтобы показать <a> с некоторым цветом и шрифтом, это зависит от вас.

Я добавил также функцию didFailProvisionalNavigation, чтобы показать предупреждение в некоторых случаях URL-адрес не является действительным что-то вроде нового HTTPTransportSecurityLayer добавляемого IOS 9, чтобы только HTTPS, в некоторых случаях вы можете использовать его для проверки URL и знать причину ошибки.

В результате получается следующий текст в нормальном UIViewController:

enter image description here

И при нажатии любого серого текста URL будет загружен в том же WKWebView, конечно, вы можете настроить это открывайтесь во внутреннем браузере, который вы делаете или что-то еще, это зависит от вас.

И тогда вы можете увидеть результат сразу же, если вы нажмете Apple,:

enter image description here

Если вместо того, чтобы вы нажмете разработчиков Apple вы можете увидеть предупреждение в действии, потому что в HTTP протокола введите ошибку в HTTPTransportSecurityLayer в iOS 9:

enter image description here

У меня есть проект, готовый загрузить в Github, если вам это нужно. Надеюсь, это поможет вам.

+0

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

+0

Можете ли вы поделиться своим проектом в GitHub? –

+0

Ответ на возвращение ответил трюком, поэтому мне не нужна дальнейшая помощь. Спасибо, тем не менее! – fredpi

Смежные вопросы