0

It seems impossible to get the UILabel to adhere to the constraints in the way that I want it to consistently. The leading and trailing space constraints seem in effect but the label is just truncating the lines instead of expanding to new lines.

please stop truncating

I do have the numberOfLines of the UILabel set to 0. I have also tried the suggestion listed here: UILabel not wrapping text correctly sometimes (auto layout) and it didn't seem to work reliably. The last thing I tried was setting the setContentCompressionResistancePriority property to Fitted and Low but it doesn't work for everything in the UITableView at the same time. In fact, depending on if the tableview gets refreshed, it looks like all the wrapping can get undone.

The only thing that I tried that seemed to work well was to set the preferredMaxLayoutWidth of the UILabel to a constant. I was just hoping to use it as a last resort to avoid calculating how wide the label should be at runtime. Surely, there's an out of the box way to get what I want.

Community
  • 1
  • 1
mango
  • 5,577
  • 4
  • 29
  • 41
  • Have given the preferable height? or calculate the height at runtime? – Sohil R. Memon Jun 18 '15 at 13:13
  • hey did you provide fix height and width constraint – Gajendra Rawat Jun 18 '15 at 13:14
  • 1
    it depends on the height of the `UILabel` instance and the font, probably the label wraps the text consistently (eventually it is a precisely calculated value only not a drama queen), so, it is possible the circumstances in your case at the edge when a very slight change of height can affect the final result (auto-layout works floats not wholes!), therefore, you might need to change the layout slightly (e.g. increase the height by 1 point, or reduce the font's size by 5%, etc...), to push away the `UILabel` from that unbalanced situation. – holex Jun 18 '15 at 13:14
  • If you have a fixed font size and the height of the label doesn't allow two or more rows to be displayed (too small) you will have a result like in your picture. Try setting a minimum font size and see if there is any difference. – Teo Jun 18 '15 at 13:17
  • The constraints just do what you've told them to. Raise the compression resistance to be higher than other items in the `UITableViewCell` and check you don't have other constraints operating at a higher priority so they take precedence. This is a good question on the topic with example answers: http://stackoverflow.com/q/15850417/558933 – Robotic Cat Jun 18 '15 at 13:22
  • @SohilR.Memon I didn't specify an explicit height but I do have top and bottom constraints for the label. Do I need a height constraint? – mango Jun 18 '15 at 13:25
  • @mango Of course, you need to calculate height for the content. otherwise you will get all the content in a row – Sohil R. Memon Jun 18 '15 at 13:28

2 Answers2

1

The key to getting it to work correctly was to ask the view to reset the layout after the constraints had been applied and all the text had been set. I merely added these lines to my custom UITableViewCell after I had set the data that it needed:

    //set data
    //set constraints

    ...

    contentView.setNeedsLayout()
    contentView.layoutIfNeeded()
 }

I realized this was the solution because the view kept reporting their initial frame sizes instead of sizes after being affected by their constraints. For some reason, all the other views looked correct but not the UILabels.

I found the solution in the answer posted here: https://stackoverflow.com/a/13542580/1637033

Community
  • 1
  • 1
mango
  • 5,577
  • 4
  • 29
  • 41
  • But this should not be needed in iOS 8, which does layout _automatically_ whenever UILabel's text changes. – matt Jun 21 '15 at 19:31
  • This worked for me!!! I'm grabbing data from an API and then needed to resize the labels after setting the text. I'm using `preferredLayoutAttributesFitting` to autoSize the cell to fit 2 labels – K. Janjuha Jul 03 '22 at 13:08
0

You can calculate height of of the UILabel runtime as per the content

func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat
    {
        let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.max))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.ByWordWrapping
        label.font = font
        label.text = text

        label.sizeToFit()
        return label.frame.height

    }
Sohil R. Memon
  • 9,404
  • 1
  • 31
  • 57
  • This seems really intensive, doesn't it? – mango Jun 18 '15 at 13:45
  • @mango This is the only option I can see to calculate dynamic height as per the content. Otherwise, provide the max height explicitly from the Storyboard – Sohil R. Memon Jun 18 '15 at 13:47
  • I'm not using a storyboard here. But I'll try specifying the max height as you suggested when I get a chance. – mango Jun 18 '15 at 14:03
  • Setting a height didn't seem to have any effect. Is it: label.frame.size.height = 12? – mango Jun 18 '15 at 22:53
  • @mango You have to pass the "Label Text", "Font if you want" and the "width of label", it will automatically return the height and then you can create the frame of the label – Sohil R. Memon Jun 18 '15 at 23:38