[ACCEPTED]-How do I vertically center UITextField Text?-alignment

Accepted answer
Score: 371
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

In swift use:

textField.contentVerticalAlignment = UIControlContentVerticalAlignment.center

0

Score: 10

This has potentially got several complicating 16 factors, some alluded to in previous answers:

  • What you're trying to align (just numbers, just letters, just uppercase letters or a mix)
  • Placeholders
  • Clear button

What you're 15 trying to align is important because of 14 which point in the font should be vertically 13 centered due to line height, ascenders, descenders 12 etc.
vertical font characteristics
(source: ilovetypography.com)

(Image thanks to http://ilovetypography.com/2009/01/14/inconspicuous-vertical-metrics/ )

When you're dealing 11 with just numbers for example, the standard 10 center alignment won't look quite right. Compare 9 the difference in the two below, which use 8 the same alignment (in the code below), one 7 of which looks correct and the other which 6 looks slightly off:

Not quite right with a mix of letters:

letters not looking centered

but looks right if it's just numbers

numbers looking centered

So, unfortunately, it 5 may need a bit of trial and error and manual 4 adjustment to get it looking visually correct.

I 3 placed the below code in a subclass of UITextField. It 2 calls superclass methods as this takes into 1 account the clear button being present.

override func awakeFromNib() {
    contentVerticalAlignment = UIControlContentVerticalAlignment.Center
}

override func textRectForBounds(bounds: CGRect) -> CGRect {
    let boundsWithClear = super.textRectForBounds(bounds)
    let delta = CGFloat(1)
    return CGRect(x: boundsWithClear.minX, y: delta, width: boundsWithClear.width, height: boundsWithClear.height - delta/2)
}

override func editingRectForBounds(bounds: CGRect) -> CGRect {
    let boundsWithClear = super.editingRectForBounds(bounds)
    let delta = CGFloat(1)
    return CGRect(x: boundsWithClear.minX, y: delta, width: boundsWithClear.width, height: boundsWithClear.height - delta/2)
}

override func placeholderRectForBounds(bounds: CGRect) -> CGRect {
    let delta = CGFloat(1)
    return CGRect(x: bounds.minX, y: delta, width: bounds.width, height: bounds.height - delta/2)
}
Score: 5

In the storyboard: Under control -> change 2 the vertical as well as horizontal alignment, as 1 to your needs.

enter image description here

Score: 1

This works fine for textField's text. But 5 if you want to use placeholder text (a text 4 that will appear while textfield is blank), on 3 iOS 7 you will encounter problems.

I solved 2 it by overriding TextField class and

- (void) drawPlaceholderInRect:(CGRect)rect

method.

Like 1 this:

- (void) drawPlaceholderInRect:(CGRect)rect
{
    [[UIColor blueColor] setFill];
    CGRect placeholderRect = CGRectMake(rect.origin.x, (rect.size.height- self.font.pointSize)/2, rect.size.width, self.font.pointSize);
    [[self placeholder] drawInRect:placeholderRect withFont:self.font lineBreakMode:NSLineBreakByWordWrapping alignment:self.textAlignment];
}

Works for both iOS7 and earlier versions.

Score: 0

You can also resolve the issue by adjusting 1 the text baseline.

// positive: up, negative:down
// NSAttributedStringKey.baselineOffset:0

let attDic: [NSAttributedString.Key: Any] = [
    .font: UIFont.systemFont(ofSize: 16),
    .baselineOffset: 0
];

textfield.placeholder = NSAttributedString(string: "....", attributes:  attDic);

More Related questions