Talha Ahmad Khan
Talha Ahmad Khan

Reputation: 3476

Swift: How to reload row height in UITableViewCell without reloading data

I have a case in which I have to reload only height of a UITableViewCell.

but if I call the function

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

it reloads the height as well as the data of the cell. How can i just control the height of cell in Swift?

This is my cellForRow block :

    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
    }

Upvotes: 39

Views: 54873

Answers (4)

Yousaf Nisar
Yousaf Nisar

Reputation: 1

You can use the view height constraint in the cell, by updating the view in cell height you can update the specific cell height.

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

Height_constraint: is the height constraint of subView in my cell.

Upvotes: -7

Alessandro Ornano
Alessandro Ornano

Reputation: 35392

About your question for example, to give a specific height dimension :

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

  return 72.0
}

But I think you have a webView inside a cell so, generally, to calculate the dynamic height of a UITableViewCell with a UIWebView: (this example have two 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)
    }
}

Upvotes: 3

Moriya
Moriya

Reputation: 7906

start an update of the tableview and then end it without changing anything.

tableView.beginUpdates()
tableView.endUpdates()

This should make the tableview set the new height

You can regulate the height by either implementing the (a)heightForRowAtIndexPath with logic setting the heights or (b)with auto layout and automatic tableview row height

A.

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

Whenever you want to change the height you would just call these two rows

tableView.beginUpdates()
tableView.endUpdates()

B.

in viewDidLoad

tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension

and then you can just expose the layout constraint that set's the cells height and access it to set the height when you want

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

Upvotes: 28

Diogo Antunes
Diogo Antunes

Reputation: 2291

You can use this code to update the cell's height without reloading their data:

tableView.beginUpdates()
tableView.endUpdates()

You can also use this method followed by the endUpdates method to animate the change in the row heights without reloading the cell.

UITableView Class Reference

Upvotes: 98

Related Questions