Все содержимое UIWebView, встроенное в UITableView

Я боролся с этим в течение двух дней, поэтому я прихожу в руки к мудрым людям в Интернете.

Я показываю статью как часть моего UITableView. Чтобы это отображалось правильно, мне нужно предоставить делегату высоту для ячейки, которую я хочу быть такой же, как высота UIWebView, поэтому я могу отключить прокрутку в WebView и полностью отобразить веб-контент в виде статическая ячейка.

Мой первый подход заключался в том, чтобы отобразить его в методе heightForRowAtIndexpath, но это, очевидно, не работает, так как мне нужно ждать, пока UIWebViewDelegate скажет мне, когда веб-представление полностью загружено и имеет высоту. Через некоторое время я нашел рабочее решение, в котором делегат веб-представления обновил высоту ячейки при загрузке веб-представления.

Работа прекращается до тех пор, пока размер экрана не изменится. Либо от поворота, либо от полноэкранного просмотра UISplitView. Я принудительно обновил его в didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation), но это заставляет его мигать примерно 10 раз, прежде чем оседать на правильную высоту. Я зарегистрировал это изменение, и кажется, что WebView вызывает себя несколько раз, вызывая цикл.

Как видно из этого журнала, начиная с момента поворота экрана.

Он мигает каждый раз, когда он перезагружается, и, как вы можете видеть, он перезагружает себя несколько раз.

Итак. Мне нужен способ показать весь контент веб-представлений внутри uitableview и надежно получить высоту при изменении размера экрана. Если кому-то это удалось, пожалуйста, скажите мне. Я дам щедрость и свой первенец ребенку всем, кто может это разрешить, поскольку это сводит меня с ума.

Вот мой соответствующий код.

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    switch indexPath.row {
case 4:
        //Content
        print("Height for row called")
        return CGFloat(webViewHeight)
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    switch (indexPath.row){
//HTML Content View
    case 4:
        let cell = tableView.dequeueReusableCellWithIdentifier("ContentCell", forIndexPath: indexPath)
        var contentCell = cell as? ContentCell
        if contentCell == nil {
            contentCell = ContentCell()
        }
        contentCell?.contentWebView.delegate = self
        contentCell?.contentWebView.scrollView.userInteractionEnabled = false
        contentCell?.contentWebView.loadHTMLString((post?.contentHTML)!, baseURL: nil)
        print("Cell For row at indexpath called")
        return contentCell!
}
func webViewDidFinishLoad(webView: UIWebView) {
    updateHeight()
}

func updateHeight(){
    let webView = (self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 4, inSection: 0)) as! ContentCell).contentWebView
    if self.webViewHeight != Double(webView.scrollView.contentSize.height) {
        print("Previous WV Height = \(self.webViewHeight), New WV Height = \(webView.scrollView.contentSize.height)")
        self.webViewHeight = Double(webView.scrollView.contentSize.height)
        tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .Automatic)
    } else {
        return
    }
}

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
    print("rotated")
        self.updateHeight()
        //tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .Automatic)
}

Ответ 1

Я решил это, изменив .Automatic на .None в анимации изменения строки. Его по-прежнему плохое решение, но, по крайней мере, оно больше не мерцает.

Ответ 2

Я бы рекомендовал вам вычислить высоту веб-представления независимо от вида таблицы и сохранить измерение как часть самих данных и использовать его для возврата в вызове heightForRowAtIndexPath. Это проще, так как вам не приходится иметь дело с вычислением высоты таблицы во время отображения табличного представления. Когда содержимое html не загружается, используйте стандартную высоту и сообщение для веб-представления.

Ответ 3

Я не вижу проблемы в вашей реализации. Трей немногие вещи Есть несколько вещей, которые вы можете проверить

func webViewDidFinishLoad(webView: UIWebView) {
    updateHeight()
    //This function may get called multiple times depending on webpage. 
}

//Use
      self.tableView.beginUpdates()
      self.tableView.endUpdates()
//Instead of
 tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .None)

    func updateHeight(){
        let webView = (self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 4, inSection: 0)) as! ContentCell).contentWebView
        if self.webViewHeight != Double(webView.scrollView.contentSize.height)
        {
            print("Previous WV Height = \(self.webViewHeight), New WV Height = \(webView.scrollView.contentSize.height)")
            self.webViewHeight = Double(webView.scrollView.contentSize.height)
            self.tableView.beginUpdates()
            self.tableView.endUpdates()
//            tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .None)
        } else {
            return
        }
    }

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation)
{
    print("rotated")
    let webView = (self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 4, inSection: 0)) as! ContentCell).contentWebView
    webView.reload();
}

Вам потребуется перезагрузить веб-просмотр при изменении ориентации.