Why does the text of UILabel not truncate given the constraints that I have set?

Viewed 571

Quite a simple setup: a UITableViewCell hosting a UIImageView and a UILabel.

The UIImageView has got a leading anchor to the cell and a fixed width. The UILabel has got a leading anchor to the UIImageView, a trailing anchor to the cell and is centred vertically. numberOfLines is set to 1, lineBreakMode is set to .byTruncatingTail and Autoshrink to Fixed font size.

From my understanding this are all conditions necessary in order to make the label truncate the text. However, it does not. Why?

Constraints:
Constraints

Properties:
Properties

Result:
Result

3 Answers

Use this class. Edit the values as you please.
I highly recommend you programmatically create cells. Constraints are a tricky business and you'll have a hard time setting them. Here I'm defining the size of the objects and their place inside of the cell. This is way is easier and cleaner in my opinion.

class tabViewCell: UITableViewCell {
    
    var label: UILabel!
    var myImageView: UIImageView!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    
      commonInit()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
   
    func commonInit() {
        //Space between items
        let sideSpace: CGFloat = 15.0
        //Hight of image and label and width of image
        let imageDimension: CGFloat = 25.0
        //width of image + space between beginning of your cell and image + space between image and label
        let labelX: CGFloat = imageDimension+(sideSpace*2)
        //Dimension of the screen - space occupied by first side space, image and space between image and label - space between label and the end of your cell
        //If you want to determine the dimension of the cell use contentView instead of UIScreen.main
        let labelWidth: CGFloat = UIScreen.main.bounds.width-labelX-sideSpace
        
        
        myImageView = UIImageView(frame: CGRect(x: sideSpace, y: 0.0, width: imageDimension, height: imageDimension))
        label = UILabel(frame: CGRect(x: labelX, y: 0.0, width: labelWidth, height: imageDimension))
        
        label.contentMode = .scaleAspectFit
        label.clipsToBounds = true
        label.numberOfLines = 1
        label.lineBreakMode = .byTruncatingTail
        label.font = UIFont.systemFont(ofSize: 15) //Change it as you please
        
        addSubview(myImageView)
        addSubview(label)
    }
}

Yes, it should work and it is working for me. Please find the screens below. I recommend doing the same setup in a different controller and try to figure out the root cause.

Just remember, the label will truncate in storyboard itself so no need to run it to test, just give a long string in storyboard.

Constraints:

Constraints

Output

Output

This may help:

let labelWidth = CGRectGetWidth(label.bounds)

    let str = "You will have 30 seconds till you give us a good impression" as NSString
    let words = str.componentsSeparatedByString(" ")

    var newStr = "" as NSString

    for word in words{

        let statement = "\(newStr) \(word) ..." as NSString
        let size = statement.sizeWithAttributes([NSFontAttributeName:label.font])
        if size.width < labelWidth {
            newStr = "\(newStr) \(word)"
        }
        else{
           break
        }
    }

    newStr = newStr.stringByAppendingString(" ...")

    self.label.text = newStr as String

Use this in your storyboard constrains:

1- give the label (Trailing, leading, top & Bottom)

2- Number of lines = 1

3- you can center your label with imageView

enter image description here

It already works with me:

enter image description here

Related