【问题标题】:Swift: How to reload row height in UITableViewCell without reloading dataSwift:如何在不重新加载数据的情况下重新加载 UITableViewCell 中的行高
【发布时间】:2016-05-24 07:08:15
【问题描述】:

我有一个案例,我只需要重新加载 UITableViewCell 的高度。

但是如果我调用函数

tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: webView.tag, inSection: 0)], withRowAnimation: .Automatic)

它会重新加载高度以及单元格的数据。 如何在 Swift 中控制单元格的高度?

这是我的 cellForRow 块:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! CustomTableViewCell1
    cell.heading.text = headerText
        return cell
    }

    else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as! CustomTableViewCell2
        ImageLoader.sharedLoader.imageForUrl(self.headerImage , completionHandler:{(image: UIImage?, url: String) in
            cell.mainImage.image = image
        })
        return cell
    }
    else if indexPath.row == 2 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell3", forIndexPath: indexPath) as! CustomTableViewCell3
        //cell.aurthorImage.image = UIImage(named : "obama")
        ImageLoader.sharedLoader.imageForUrl(self.headerImage , completionHandler:{(image: UIImage?, url: String) in
            cell.aurthorImage.image = image
        })
        cell.aurthorImage.tag = aurthorID
        cell.aurthorImage.layer.cornerRadius = cell.aurthorImage.frame.height/2
        cell.aurthorImage.clipsToBounds = true
        cell.aurthorImage.userInteractionEnabled = true
        cell.aurthorImage.addGestureRecognizer(aurthorImageTapRecignizer)
        cell.aurthorName.text = self.authorName
        cell.time.text = self.time
        self.followButton = cell.followButton
        return cell
    }

    else if indexPath.row == 3 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell4", forIndexPath: indexPath) as! CustomTableViewCell4
        let htmlHeight = contentHeights[indexPath.row]

        cell.webElement.tag = indexPath.row
        cell.webElement.delegate = self
        cell.webElement.loadHTMLString(HTMLContent, baseURL: nil)
        cell.webElement.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight)

        return cell
    }
    else if indexPath.row == 4 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! CustomTableViewCell1
        cell.heading.text = "Related Posts"
        return cell
    }
    else if indexPath.row == 5{
        let cell = tableView.dequeueReusableCellWithIdentifier("cell6", forIndexPath: indexPath) as! CustomTableViewCell6
        return cell

    }
    else if indexPath.row == 6 {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! CustomTableViewCell1
        cell.heading.text = "Comments"
        return cell
    }
    else if indexPath.row == 7 {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell5", forIndexPath: indexPath) as! CustomTableViewCell5


        let htmlHeight = contentHeights[indexPath.row]
        self.commentSection = cell.commentsView
        self.commentSection.tag = indexPath.row
        self.commentSection.delegate = self
        let url = NSURL(string: commentsURL)
        let requestObj = NSURLRequest(URL: url! )
        self.commentSection.loadRequest(requestObj)
        self.commentSection.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight)
            commentSectionDidNotLoad = false

            return cell
    }
    else {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! CustomTableViewCell1
        cell.heading.text = headerText
        return cell
    }

【问题讨论】:

  • 您不想在重新加载时更新数据?
  • 是的,数据不应该被重新加载
  • 然后,您必须将条件放在 cellForRow 上。但我认为,如果数据更新,那么它必须反映到表中。
  • 或者,如果您使用文本字段或该单元格中的任何内容,则必须保存数据。然后你重新加载然后数据不会改变!
  • 是的,但我使用的是不应重新加载的 webView

标签: swift uitableview


【解决方案1】:

您可以使用此代码更新单元格的高度,而无需重新加载其数据:

tableView.beginUpdates()
tableView.endUpdates()

您也可以使用此方法后跟 endUpdates 方法来动画化行高的变化,而无需重新加载单元格。

UITableView Class Reference

【讨论】:

  • 我应该在哪里以及如何使用它??
  • 每当你想更新高度。可能在单击单元格后,取决于您的用例
  • 假设我想将第 5 行的行高更改为 CGFloat(100) ,我应该在 tableView.beginUpdates() 和 tableView.endUpdates() 之间写什么
  • 我使用 reloadRowsAtIndexPaths:withRowAnimation: 在标签的高度发生变化时重新加载我的单元格(基于其文本)...我不确定主要区别是什么,但我遇到了问题似乎我的表格视图尚未加载,并且在 endUpdates 调用中出现内部不一致崩溃。使用reloadRowsAtIndexPaths: 可以获取单元格(cellForRowAtIndexPath:),验证它是否存在并更新它,然后重新加载,就可以控制动画了。
  • 嗯...实际上我刚刚遇到了 reloadRowsAtIndexPaths 的断言错误,所以如果你没有做正确的事情,仍然存在问题 :) 但是能够控制动画很好。
【解决方案2】:

开始更新 tableview,然后结束它而不做任何更改。

tableView.beginUpdates()
tableView.endUpdates()

这应该让 tableview 设置新的高度

您可以通过使用设置高度的逻辑实现 (a)heightForRowAtIndexPath 或 (b) 使用自动布局和自动 tableview 行高来调节高度

一个。

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
     if [your condition, row == 5 in your comment] {
          return 100
     } else {
         return 40
     }
}

当你想改变高度时,你只需调用这两行

tableView.beginUpdates()
tableView.endUpdates()

B.

在 viewDidLoad 中

tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension

然后您可以公开设置单元格高度的布局约束,并在需要时访问它以设置高度

cell.heightConstraint.constant = 100
tableView.beginUpdates()
tableView.endUpdates()

【讨论】:

  • 我应该在哪里以及如何使用它??
  • 假设我想将第 5 行的行高更改为 CGFloat(100) ,我应该在 tableView.beginUpdates() 和 tableView.endUpdates() 之间写什么
【解决方案3】:

例如,关于您的问题,给出特定的高度尺寸:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
  if indexPath.row == 3 {
    return 50.0
  }

  return 72.0
}

但我认为您在单元格内有一个 webView,因此通常要使用 UIWebView 计算 UITableViewCell 的动态高度: (这个例子有两个 webViews)

class MyTableViewController: UITableViewController, UIWebViewDelegate
{
    var content : [String] = ["<!DOCTYPE html><html><head><title>Page Title</title></head><body><h1>My First Heading</h1><p>My first paragraph</p></body></html>", "<HTML><HEAD><TITLE>Coca-Cola</TITLE></HEAD><BODY>In Chinese, Coca-Cola means Bite the Wax Tadpole</BODY></HTML>"]
    var contentHeights : [CGFloat] = [0.0, 0.0]

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCell", forIndexPath: indexPath) as! MyCustomCell
        let htmlString = content[indexPath.row]
        let htmlHeight = contentHeights[indexPath.row]

        cell.webView.tag = indexPath.row
        cell.webView.delegate = self
        cell.webView.loadHTMLString(htmlString, baseURL: nil)
        cell.webView.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight)
        return cell
    }
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        return contentHeights[indexPath.row]
    }
    func webViewDidFinishLoad(webView: UIWebView)
    {
        if (contentHeights[webView.tag] != 0.0)
        {
            // height knowed, no need to reload cell
            return
        }
        contentHeights[webView.tag] = webView.scrollView.contentSize.height
        tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: webView.tag, inSection: 0)], withRowAnimation: .Automatic)
    }
}

【讨论】:

  • 是的,巧合的是,您在回复中写了我的案例,但我正在从 URL 加载 webview。这在我的情况下不起作用。 webview 没有完全加载,在它完成加载之前,调用 webViewDidFinishLoad 并且行高被卡在小于所需的高度
  • 可能你加载了你的 html 并且在主 html 文件之后还加载了其他 javascripts 函数,在这种情况下你可以使用 webView.stringByEvaluatingJavaScriptFromString 来处理它。
  • @AlessandroOrnano reloadRowsAtIndexPaths 将导致 webview 再次加载 html。有没有办法在不重新加载的情况下增加单元格的高度。我看到很多帖子建议 beginUpdates endUpdates 但它似乎不起作用。你有什么建议吗?
  • @ShivamPokhriyal beginUpdates endUpdates 组合是 Apple 官方指南所建议的,如果你在主线程中调用它,而不是在回调或动画上下文中调用它,它会很好地工作。你应该在 @987654325 中调用它@了解我所说的..
  • 实际上它确实调用了tableView的heightForRow委托,这增加了行的高度,但单元格的视图没有更新。我更新了约束,但它不影响。调用 layoutIfNeeded、setNeedsLayout、setNeedsUpdateCONstraints 但没有任何效果
【解决方案4】:

您可以在单元格中使用视图高度约束,通过更新单元格高度中的视图可以更新特定的单元格高度。

let height = cell.Height_constraint.constant
cell.Height_constraint.constant = height + 200 //200 you can use any number

Height_constraint:是我的cell中subView的高度约束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多