1

How can I make the TableViewCell change height to make the UILabel fit?

I am not using auto layout in my project, and because this is a big project I am not going to change to that either - so I need a fix that works without auto layout.

This is my CommentsViewController.swift code:

import UIKit
import Parse
import ActiveLabel

class CommentsViewController: UITableViewController, UITextFieldDelegate {

    var commentsArray: [String] = []
    var currentObjID = ""
    @IBOutlet var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
        self.textField.delegate = self

        queryComments()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func queryComments(){
        self.commentsArray.removeAll()
        let query = PFQuery(className:"currentUploads")
        query.whereKey("objectId", equalTo: self.currentObjID)
        query.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error: NSError?) -> Void in
            if error == nil {
                if let objects = objects {
                    for object in objects {

                        let list: AnyObject? = object.objectForKey("comments")

                        self.commentsArray = list! as! NSArray as! [String]
                        self.tableView.reloadData()
                        self.textField.text = ""
                    }
                }
            } else {
                print("\(error?.userInfo)")
            }
        }
        self.sendButton.enabled = true
        self.refreshButton.enabled = true
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return commentsArray.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell:TableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell;

        if self.commentsArray.count > indexPath.row{
            cell.commentsText.font = UIFont.systemFontOfSize(15.0)
            cell.commentsText.text = commentsArray[commentsArray.count - 1 - indexPath.row]
            cell.commentsText.numberOfLines = 0
        }

        return cell
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        let height:CGFloat = self.calculateHeightForString(commentsArray[indexPath.row])
        return height + 70.0
    }

    func calculateHeightForString(inString:String) -> CGFloat
    {
        let messageString = inString
        let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(15.0)]
        let attrString:NSAttributedString? = NSAttributedString(string: messageString, attributes: attributes)
        let rect:CGRect = attrString!.boundingRectWithSize(CGSizeMake(300.0,CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil )//hear u will get nearer height not the exact value
        let requredSize:CGRect = rect
        return requredSize.height  //to include button's in your tableview

    }
}

Screenshot: enter image description here

This makes all the cells very big, even the cells that only has 1 line. Any ideas?

Roduck Nickes
  • 1,021
  • 2
  • 15
  • 41

3 Answers3

0

You can use heightForRowAtIndexPath to edit a table cell's height. This is a delegate method you'll be able to use after subclassing and setting your tableview's delegate property (IBoutlet or view.delegate = self)

See this thread if you don't already know your label's height: how to give dynamic height to UIlabel programatically in swift?

The way this works is you'll give a height for every index path row (ideally out of some collection - array). As your table loads cells it will automatically adjust for you.

Community
  • 1
  • 1
MarcJames
  • 189
  • 9
0

Can you tell what happens when you remove the heightForRowAtIndexPath method and add this in your viewDidLoad:

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 80

With these two lines we instruct the tableview to calculate the cell's size matching its content and render it dynamically.

EDIT: I just read you don't want to use Auto Layout. I don't think if this'll still work in that case.

Duy Tran
  • 101
  • 6
  • It does not work. Can i use auto layout on ONLY that view controller, in the same storyboard? – Roduck Nickes Jan 26 '16 at 21:33
  • Yes, you can. If you have a custom cell, just pin the label on every side to the Content View and set the numberOfLines to 0. If you're using the default cell, you don't have to use Auto Layout and then you only have to set the numberOfLines to 0. – Duy Tran Jan 26 '16 at 21:41
  • Can you show me the constraints in the cell and did you remove the heightForRow.... ? – Duy Tran Jan 27 '16 at 15:20
  • As mentioned earlier, i am not using auto layout :), and yes i did remove – Roduck Nickes Jan 28 '16 at 08:58
  • Yes, that's quite logical, because you have to use Auto-Layout to make it work as I've mentioned. If it's only text you want to display, I suggest you use the default UITableviewcell and set the numberOfLines to 0 which should in theory also work. – Duy Tran Jan 28 '16 at 12:51
0

Im not 100% sure without Autolayout but you could set the estimated row height along with dimension. So in your viewDidLoad enter this

    self.tableView.estimatedRowHeight = //Largest Cell Height
    self.tableView.rowHeight = UITableViewAutomaticDimension
Devster101
  • 578
  • 4
  • 18