Ios UIWebView';s嵌入UITableView中的全部内容

Ios UIWebView';s嵌入UITableView中的全部内容,ios,swift,uitableview,uiwebview,autolayout,Ios,Swift,Uitableview,Uiwebview,Autolayout,我已经为此挣扎了两天,所以我来到互联网上的智者面前 我正在显示一篇文章,作为我的UITableView的一部分。为了正确显示,我需要为代理指定单元格的高度,我希望该高度与UIWebView的高度相同,这样我就可以禁用WebView上的滚动,并将整个web内容显示为静态单元格 我的第一种方法是在heightforrowatinexpath方法中渲染它,但这显然不起作用,因为我需要等待UIWebViewDelegate来告诉我web视图何时已完全加载且具有高度。过了一会儿,我找到了一个可行的解决方案

我已经为此挣扎了两天,所以我来到互联网上的智者面前

我正在显示一篇文章,作为我的
UITableView
的一部分。为了正确显示,我需要为代理指定单元格的高度,我希望该高度与
UIWebView
的高度相同,这样我就可以禁用WebView上的滚动,并将整个web内容显示为静态单元格

我的第一种方法是在
heightforrowatinexpath
方法中渲染它,但这显然不起作用,因为我需要等待
UIWebViewDelegate
来告诉我web视图何时已完全加载且具有高度。过了一会儿,我找到了一个可行的解决方案,它使用web视图委托在加载web视图时刷新单元格高度

在屏幕大小改变之前,屏幕工作正常。从旋转或从全屏幕my
UISplitView
。我在
didRotateFromInterfaceOrientation(fromInterfaceOrientation:UIInterfaceOrientation)
中强制对其进行更新,但这会导致它在设置到正确高度之前闪烁大约10次。我记录了这个变化,看起来WebView多次调用自己,导致了一个循环

如日志所示,从我旋转屏幕开始

它每次重新加载时都会闪烁一次,正如您所看到的,它会多次重新加载自己

所以。我需要一种在uitableview中显示整个web视图内容的方法,并在屏幕大小改变时可靠地获取高度。如果有人曾经以任何方式处理过这个问题,请告诉我。我会给任何能解决这个问题的人一笔赏金和我的长子,因为这让我发疯

这是我的相关代码

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)
}

我认为您的实现没有问题。很少的事情 你可以检查的东西很少

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();
}

您需要在方向更改时重新加载webview。

我建议您独立于表视图计算web视图高度,并将尺寸存储为数据本身的一部分,并在heightForRowAtIndexPath调用中使用它返回高度。这是一种更简单的方法,因为在表格视图显示期间,您不必计算表格高度。未加载html内容时,请为web视图使用标准高度和消息

我通过将行更改动画中的.Automatic更改为.None解决了这个问题。这仍然是一个糟糕的解决方案,但至少它不再闪烁

我以前也遇到过这个问题,而且由于UIWebView通常是一个神奇的黑盒,所以我经常使用一种变通方法。假设您的文章主要是文本,请考虑通过UITExtVIEW本地显示HTML内容,HTML作为属性字符串。关于在UITextView中显示HTML的基本示例,请看下面的答案:@AaronAsh我对此进行了研究,但对于我的用例来说,带有HTML内容的属性标签解析速度太慢,而且不支持表。遗憾的是,将其放入tableview单元格应该不会有太大困难,请看这里:另外,我也听说有人抱怨HTML解析速度慢,但在实践中从未见过。值得继续拍摄吗?看起来应用程序正在为大小的变化设置动画,并在动画过程中多次调用updateHeight()。在updateHeight()中放置一个断点,以查看从何处调用它。我猜您在代码的另一个地方也有它。旁注:从您的代码中,我了解到您的表中只有一个单元格具有嵌入的tableView?然后,我会在VC中处理整个webview逻辑(包括实例化),并在单元格出现在屏幕上时将webview添加为单元格的子视图(例如使用
willDisplayCell
),这样可以避免在单元格离开屏幕时重新加载所有内容,并等待webview显示。