Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center vertically in UILabel with autoshrink

Tags:

ios

uilabel

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.)

like image 703
Paul Cezanne Avatar asked Jul 31 '13 13:07

Paul Cezanne


People also ask

How do you set the center of an element vertically?

For example, if you're trying to align something horizontally OR vertically, it's not that difficult. You can just set text-align to center for an inline element, and margin: 0 auto would do it for a block-level element.


2 Answers

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 
like image 164
TomSwift Avatar answered Oct 02 '22 15:10

TomSwift


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)

like image 36
Peter Lapisu Avatar answered Oct 02 '22 16:10

Peter Lapisu