简体   繁体   中英

Expand label/cell size based on text size in UITableView Swift

I am new to iOS development. I have a problem with my cell sizing. I am not using Auto-Laylout feature. My current TableView cell looks something like this . I want to make the label size which is selected in the image to be extended dynamically based on the text content of that Label.

Thanks in advance.

i think the swift version like below, it calculates nearer values not the exact height, for example

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {

 var messageArray:[String] = []
 override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
      messageArray = ["One of the most interesting features of Newsstand is that once an asset downloading has started it will continue even if the application is suspended (that is: not running but still in memory) or it is terminated. Of course during while your app is suspended it will not receive any status update but it will be woken up in the background",
                      "In case that app has been terminated while downloading was in progress, the situation is different. Infact in the event of a finished downloading the app can not be simply woken up and the connection delegate finish download method called, as when an app is terminated its App delegate object doesn’t exist anymore. In such case the system will relaunch the app in the background.",
                      " If defined, this key will contain the array of all asset identifiers that caused the launch. From my tests it doesn’t seem this check is really required if you reconnect the pending downloading as explained in the next paragraph.",
                      "Whale&W",
                      "Rcokey",
                      "Punch",
                      "See & Dive"]
}

in the above we have an array which contains string of different length

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

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell;
    if(cell == nil)
    {
        cell = UITableViewCell(style:UITableViewCellStyle.default, reuseIdentifier: "CELL")
        cell?.selectionStyle = UITableViewCellSelectionStyle.none
    }
    cell?.textLabel.font = UIFont.systemFontOfSize(15.0)
    cell?.textLabel.sizeToFit()
    cell?.textLabel.text = messageArray[indexPath.row]
    cell?.textLabel.numberOfLines = 0
    return cell!;
}

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

func calculateHeight(inString:String) -> CGFloat
{
    let messageString = inString
    let attributes : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 15.0)]

    let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)

    let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

    let requredSize:CGRect = rect
    return requredSize.height
}

try it in a new project just add the tableview and set its datasource and delegate and past the code above and run

the result will be like below

在此输入图像描述

Try to override methods:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Complete solution:

In iOS 8, Apple introduces a new feature for UITableView known as Self Sizing Cells. Prior to iOS 8, if you displayed dynamic content in table view with varied row, you need to calculate the row height on your own.

In summary, here are the steps to implement when using self sizing cells:

• Add auto layout constraints in your prototype cell

• Specify the estimatedRowHeight of your table view

• Set the rowHeight of your table view to UITableViewAutomaticDimension

Expressing last two points in code, its look like:

tableView.estimatedRowHeight = 43.0;
tableView.rowHeight = UITableViewAutomaticDimension

You should add it in viewDidLoad method.

With just two lines of code, you instruct the table view to calculate the cell's size matching its content and render it dynamically. This self sizing cell feature should save you tons of code and time.

In Attributes Inspector of your UILabel, change Lines value to 0, so label will automatically adjust the number of lines to fit the content.

Please note that first point is required and remember that you cannot use self sizing cell without applying auto layout.

If you are note familiar with auto layout, please read this, it will be enough:

https://developer.apple.com/library/mac/recipes/xcode_help-IB_auto_layout/chapters/pin-constraints.html

Or, easier way to set auto layout, but maybe not be what you exactly expected is to clear all of your constraints, go to Resolve Auto Layout Issues and for All Views click on Reset to Suggested Constraints.

Just add this in Viewdidload

tableView.estimatedRowHeight = 44.0 
tableView.rowHeight = UITableViewAutomaticDimension
func calculateHeight(inString:String) -> CGFloat
       {
           let messageString = inString
           let attributes : [NSAttributedString.Key : Any] = [NSAttributedString.Key(rawValue:
   NSAttributedString.Key.font.rawValue) : UIFont.systemFont(ofSize:
   15.0)]

           let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)
           let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude),
   options: .usesLineFragmentOrigin, context: nil)

           let requredSize:CGRect = rect
           return requredSize.height
       }

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