choise
choise

Reputation: 25244

Set maximum number of lines for UILabel

I need to do some special alignment with a UILabel.

I want it to have 1 to 3 lines, whatever content it has.

Currently I'm doing it something like this:

label.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:14.0f];
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 0;
label.lineBreakMode = UILineBreakModeWordWrap;

label.frame = CGRectMake(114.0f, 88.0f, 187.0f, 0.0f);
[label sizeToFit];

which works great if the text is not too long. if the string is something like @"Hello World" the UILabel is only 14 points high, if it is some way longer it expands.

Now I want that the text should add it's default ... triple dots if the text gets too long for three lines, but with the setting on top it expands to the fourth line.

How do I achieve this?

Upvotes: 28

Views: 29505

Answers (6)

algrid
algrid

Reputation: 5954

This seems to work for me (using autolayout):

    label.numberOfLines = 0

    // max height for 3 lines, this value worked for me
    // you can try a slightly larger value if needed
    let heightLimit = label.font.lineHeight * 3 + 0.5

    label.heightAnchor.constraint(lessThanOrEqualToConstant: heightLimit).isActive = true

The idea is to limit the height with a lessThanOrEqual relation. If the text is small enough, then the height will be defined by label's sizeToFit automatically.

Upvotes: 2

Sean Kang
Sean Kang

Reputation: 59

The "Lines" setting in Interface Builder controls the maximum number of lines.

Check the tooltip of the Lines option in Xcode's Interface Builder:

Number Of Lines - UILabel numberOfLines

The maximum number of lines to use for rendering text.

tooltip

Upvotes: 1

James Barwick
James Barwick

Reputation: 31

I thought I would give it a try:

func heightForStringDrawing(myString: String, myFont:UIFont, myWidth:CGFloat) -> (CGFloat, Int) {
    var tc = NSTextContainer(size: CGSize(width: myWidth, height:CGFloat(FLT_MAX)))
    var ts = NSTextStorage(string: myString)
    var lm = NSLayoutManager()
    lm.addTextContainer(tc)
    ts.addLayoutManager(lm)
    ts.addAttribute(NSFontAttributeName, value: myFont, range: NSMakeRange(0, ts.length))
    tc.lineFragmentPadding = 0.0
    lm.glyphRangeForTextContainer(tc)
    let height = lm.usedRectForTextContainer(tc).height
    let lines = Int(Float(height / myFont.lineHeight))
    return (height, lines)
}

Comments are certainly welcome! I adopted this from: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Tasks/StringHeight.html

Upvotes: 3

Abh
Abh

Reputation: 124

Call getStringSize. It will return a variable of type StringSize and decide dynamically number of lines.

struct StringSize {

    int numberOfLine;
    float height;
    float width;

};

typedef struct StringSize StringSize;



+(StringSize)getStringSize:(NSString *)string ofWidth:(float)width  FontSize:(id)font {

    StringSize sizeForString;

    if(string){
        CGSize size = CGSizeMake(width, 400.0f);
        CGSize appStringSize = [string sizeWithFont:(UIFont *)font constrainedToSize:size     lineBreakMode:UILineBreakModeTailTruncation];
        CGSize sizeString = [string sizeWithFont:font];    

        sizeForString.width = appStringSize.width;
        sizeForString.height = appStringSize.height;
        sizeForString.numberOfLine = (int)(sizeForString.height/sizeString.height);
    }else {
        sizeForString.width = 0;
        sizeForString.height = 0;
        sizeForString.numberOfLine = 0;
    }

    return sizeForString;
}

Upvotes: 0

debleek63
debleek63

Reputation: 1189

label.numberOfLines = 3;
CGSize size = [label.text sizeWithFont:label.font
                     constrainedToSize:CGSizeMake(SOME_WIDTH,
                                                  3 * label.font.lineHeight)
                         lineBreakMode:UILineBreakModeWordWrap];
label.bounds = CGRectMake(0, 0,
                          size.width,
                          size.height);

Upvotes: 21

Gil
Gil

Reputation: 3638

Just set label.numberOfLines = 3;.

It is somewhat mislabeled, as it actually holds the maximum amount of lines to display.

Upvotes: 23

Related Questions