Center vertically in UILabel with autoshrink

Solution 1:

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:

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:

-(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