UIWebView的全部内容嵌入在UITableView中

时间:2016-01-10 03:25:27

标签: ios swift uitableview uiwebview autolayout

我已经为这两天苦苦挣扎了,所以我和互联网的聪明人一起来。

我正在展示一篇文章作为UITableView的一部分。为了正确显示,我需要给代表一个单元格的高度,我希望它与UIWebView的高度相同,所以我可以在WebView上禁用滚动并显示Web内容它完全是一个静态的细胞。

我的第一种方法是在heightForRowAtIndexpath方法中呈现它,但这显然不起作用,因为我需要等待UIWebViewDelegate告诉我何时Web视图已完全加载并且具有高度。过了一会儿,我发现了一个工作解决方案,它使用Web视图委托在加载Web视图时刷新单元格高度。

在屏幕尺寸发生变化之前,工作正常。来自旋转或完全筛选我的UISplitView。我在didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation)强制对其进行更新,但这导致它在达到正确高度之前闪烁约10次。我记录了这个更改,似乎WebView多次调用自身,导致循环。

this日志中可以看出,从我旋转屏幕开始。

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

因此。我需要一种在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)
}

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我建议您独立于表视图计算Web视图高度,并将维度存储为数据本身的一部分,并使用它返回heightForRowAtIndexPath调用。它更容易,因为您不必在表视图显示期间处理计算表高度。未加载html内容时,请使用标准高度和Web视图的消息。

答案 2 :(得分:-1)

我认为您的实施中没有问题。特雷几件事 你可以检查的东西很少

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。