Center vertically in UILabel with autoshrink

IosUilabel

Ios Problem Overview


This is a little different from all the other "How do I center the text in a UILabel" questions here...

I have a UILabel with some text in it, I want to center the text vertically in the UILabel. What's the big deal, right? That's the default. The problem comes because my text is dynamic and I have autoshrink turn on. As the text grows larger, the font size shrinks. You get this behavior.

enter image description here

Notice that the font baseline has not moved, I want it to move so the numbers are centered vertically in the UILabel's frame.

Easy, right? I just remember the frame's original center in viewDidLoad

    self.workoutTimeCenter = _workoutTimeLabel.center;

and then I call sizeToFit after I change the the text, right?

    [_workoutTimeLabel sizeToFit];
    _workoutTimeLabel.center = _workoutTimeCenter;

Well, sizeToFit did, I guess, exactly what it was supposed to do, resize the frame so the text fits without shrinking!

enter image description here

How can I vertically center the text in a UILabel while respecting baselines and autoshrink? (Note, an iOS5 and later solution is fine and I can even deal with an iOS6 and later solution.)

Ios Solutions


Solution 1 - Ios

In my experience you can just set the -[UILabel baselineAdjustment] property to UIBaselineAdjustmentAlignCenters to achieve the effect you're describing.

From the docs:

> ## baselineAdjustment > > Controls how text baselines are adjusted when text > needs to shrink to fit in the label. > > @property(nonatomic) UIBaselineAdjustment baselineAdjustment > > ### Discussion > If the adjustsFontSizeToFitWidth property is set to YES, > this property controls the behavior of the text baselines in > situations where adjustment of the font size is required. The default > value of this property is UIBaselineAdjustmentAlignBaselines. This > property is effective only when the numberOfLines property is set to > 1.

and

> UIBaselineAdjustmentAlignCenters
> Adjust text based relative to the center of its bounding box.

EDIT: adding a full view-controller that demonstrates this:

@interface TSViewController : UIViewController
@end

@implementation TSViewController

- (void) addLabelWithFrame: (CGRect) f baselineAdjustment: (UIBaselineAdjustment) bla
{
    UILabel* label = [[UILabel alloc] initWithFrame: f];
    label.baselineAdjustment = bla;
    label.adjustsFontSizeToFitWidth = YES;
    label.font = [UIFont fontWithName: @"Courier" size: 200];
    label.text = @"00";
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor lightGrayColor];
    label.userInteractionEnabled = YES;
    [self.view addSubview: label];
    
    UIView* centerline = [[UIView alloc] initWithFrame: CGRectMake(f.origin.x, f.origin.y+(f.size.height/2.0), f.size.width, 1)];
    centerline.backgroundColor = [UIColor redColor];
    [self.view addSubview: centerline];
    
    UITapGestureRecognizer* tgr = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(onTap:)];
    [label addGestureRecognizer: tgr];
}

- (void) viewDidLoad
{
    [super viewDidLoad];
    
    [self addLabelWithFrame: CGRectMake(0, 0, 320, 200)
         baselineAdjustment: UIBaselineAdjustmentAlignCenters];
    
    [self addLabelWithFrame: CGRectMake(0, 220, 320, 200)
         baselineAdjustment: UIBaselineAdjustmentAlignBaselines];
}

- (void) onTap: (UITapGestureRecognizer*) tgr
{
    UILabel* label = (UILabel*)tgr.view;
    NSString* t = [label.text stringByAppendingString: @":00"];
    label.text = t;
}

@end

Solution 2 - Ios

when working in IB, be sure to set align baselines to center

enter image description here

Note: line break CANNOT be word wrap for this to work, so it will NOT work multiline (good to set the line break to Truncate tail)

Solution 3 - Ios

-(void)fitVerticallyToLabel:(UILabel *)lbl
{
    CGFloat fontSize = lbl.frame.size.width / lbl.text.length;
    [lbl setFont:[UIFont fontWithName:@"Helvetica-Bold" size:fontSize]];

    CGRect rect = lbl.frame;
    rect.origin.y += rect.size.height - fontSize;
    rect.size.height = fontSize;
    [lbl setFrame:rect];
}

How to Use: Call this method after setting the text to your label.

    label.text = @"text";
    [self fitVerticallyToLabel:label];

enter image description hereenter image description here

Note: I ahev taken UILabel from xib. You can take it programmatically too in that case you will have to set its text alignment NSTextAlignMentCenter

Solution 4 - Ios

Try to implement this logic:

-(void)adjustLabel1Text1:(NSString *)text1 
{
    UILabel *lbl_first = [UIFont fontWithName:@"Helvetica" size:12];
   
   
    
    text1 = [text1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
   
    
    float hedingLblHeight = [self calculateHeightOfTextFromWidth:text1 : [UIFont fontWithName:@"Helvetica" size:12] :118 :UILineBreakModeWordWrap];
    
    lbl_first.text=text1;
    
    
    [lbl_first setFrame:CGRectMake(lbl_first.frame.origin.x, lbl_first.frame.origin.y, 118, hedingLblHeight)];
    lbl_first.lineBreakMode = UILineBreakModeWordWrap;
    lbl_first.numberOfLines = 0;
    [lbl_first sizeToFit];
    
    


//////////Adjust the lable or any UIControl below this label accordingly.

    float endResultHeight=[self calculateHeightOfTextFromWidth:text2 : [UIFont fontWithName:@"Helvetica" size:15] :299 :UILineBreakModeWordWrap];
    
    if(hedingLblHeight>secondImgTitleHeight)
    {
    [lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];
    }
    else
    {
        [lbl_endResult setFrame:CGRectMake(lbl_endResult.frame.origin.x, lbl_first.frame.origin.y+lbl_first.frame.size.height+5, 299, endResultHeight)];

    }
    
    lbl_endResult.lineBreakMode=UILineBreakModeWordWrap;
    lbl_endResult.numberOfLines = 0;
    [lbl_endResult sizeToFit];
    
    
 
}

-(float) calculateHeightOfTextFromWidth:(NSString*)text : (UIFont*) withFont:(float)width :(UILineBreakMode)lineBreakMode
{
    
    CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
    
    return suggestedSize.height;
}

It has helped me a lot.Hope it works for you.

Solution 5 - Ios

Try

yourLabel.textAlignment = UITextAlignmentCenter;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaul CezanneView Question on Stackoverflow
Solution 1 - IosTomSwiftView Answer on Stackoverflow
Solution 2 - IosPeter LapisuView Answer on Stackoverflow
Solution 3 - IosTheTigerView Answer on Stackoverflow
Solution 4 - IosAniket KoteView Answer on Stackoverflow
Solution 5 - IosNasirView Answer on Stackoverflow