简体   繁体   中英

How to change height of table row to fit UILabel


I am writing a messaging application which has a table view that outputs messages between two users. The problem I have run into is resizing the table rows to fit the entire UILabel. As of right now, I do not have a database hooked up to display any messages, just predefined strings that are acting as dummy messages to make sure that the table rows resize correctly.
I have a function that determines the height required for a text label, however I am having trouble making each row resize themselves to this constraint. Thank you for your time
Code:

//
//  chatViewController.swift
//  collaboration
//
//  Created by nick on 11/21/15.
//  Copyright © 2015 Supreme Leader. All rights reserved.
//

import UIKit

class chatViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!

@IBOutlet weak var testLabel: UILabel!

var messages: NSMutableArray = NSMutableArray()

func tableView(tableView: UITableView, numberOfRowsInSection Section: Int) -> Int {
    return self.messages.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! chatTableViewCell
    cell.messageLabel?.text = self.messages.objectAtIndex(indexPath.row) as? String
    print(requiredHeight(self.messages.objectAtIndex(indexPath.row) as! String))

    tableView.estimatedRowHeight = requiredHeight(self.messages.objectAtIndex(indexPath.row) as! String)
    tableView.rowHeight = UITableViewAutomaticDimension

    return cell
}

func requiredHeight(text:String) -> CGFloat {
    let font = UIFont(name: "Helvetica", size: 16.0)
    let label:UILabel = UILabel(frame: CGRectMake(0, 0, 200, CGFloat.max))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.ByWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()
    return label.frame.height
}

override func viewDidLoad() {
    super.viewDidLoad()
    let receivedUsername = NSUserDefaults.standardUserDefaults().stringForKey("usernameToMessageWith")
    testLabel.text = "\(receivedUsername! as String)"
    messages.addObject("dfsdfdfsdfsdfsdf")
    messages.addObject("You: and i i iiiknkjdf lorem ipsum i really like economics class because i can program as opposed to actually doing work")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

}

I would strongly recommend using xib file and setting autolayout there. Then your estimated height would work as expected.

Other then that, you can simply return calculated height calling it form heightForRowAtIndexPath . That way you will use separate height for each cell. For instance:

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
        return requiredHeight(self.messages.objectAtIndex(indexPath.row) as! String)
}

Again, I would try autolayout first.

I hope I understood correctly. After looking at your code I would suggest the following:

Use AutoLayout.

Set the subviews with Trailing/Leading and Top/Bottom Constraints in relation to the uitableviewcell.

You can then use Apple's AutomaticDimension feature by activating it once.

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    self.tableView.estimatedRowHeight = 44.0
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.reloadData()
}

Do not use the custom row height feature in your prototype cells. Do not calculate the row height automatically. Set the rowHeight to UITableViewAutomaticDimension once and not within the cellForRowAtIndexPath method.

Everything should work fine then.

Based on your comment, additional steps for your solution: Please check: The UILabel properties: "Lines" should be set to "0" and "Line Breaks" should be set to "Word Wrap"

In your storyboard table view cell inspector, you can see the cell row height is fixed. So in the view did load, set the estimated row height to the one in storyboard and set the row height to get its height automatically. Also inspect the label in storyboard and set Lines = 0 to show multiple lines.

override func viewDidLoad() {
     super.viewDidLoad()

     tableView.estimatedRowHeight = tableView.rowHeight
     tableView.rowHeight = UITableViewAutomaticDimension
}

You should apply auto layout constraints to UILabel with respect to content view through a storyboard or programmatically. Set leading , trailing , top and bottom constraints equals to zero . Also apply aspect ratio to UILabel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM