Heena
Heena

Reputation: 2358

UITextField placeholder string is always Top aligned in ios7

I have subclass the UITextField class and did the below code

- (void)drawPlaceholderInRect:(CGRect)rect
{

    [self.placeHolderTextColor setFill];
    [self.placeholder drawInRect:rect
                        withFont:self.placeHolderFont
                   lineBreakMode:NSLineBreakByTruncatingTail
                       alignment:NSTextAlignmentLeft];

}

I have also written self.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; line of code

This placeholder text is properly center aligned in ios6 but not in ios7 it is showing top aligned.

Although text I type is appearing centered.It only has issue with placeholder string.

I have tried with xib to set placeholder string.In XIB it is showing properly but when I run the code textfield placeholder is top aligned.

Any workaround for this?

Vadoff's answer worked for me. Still this is the full implementation that might help anyone with the same issue.

drawInRect method is deprecated in ios7 and drawInRectWithAttributes works

- (void)drawPlaceholderInRect:(CGRect)rect
{

    [self.placeHolderTextColor setFill];

    CGRect placeholderRect = CGRectMake(rect.origin.x, (rect.size.height- self.placeHolderFont.pointSize)/2 - 2, rect.size.width, self.placeHolderFont.pointSize);
    rect = placeholderRect;

    if(iOS7) {

        NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init];
        style.lineBreakMode = NSLineBreakByTruncatingTail;
        style.alignment = self.placeHolderTextAlignment;


        NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:style,NSParagraphStyleAttributeName, self.placeHolderFont, NSFontAttributeName, self.placeHolderTextColor, NSForegroundColorAttributeName, nil];

        [self.placeholder drawInRect:rect withAttributes:attr];


    }
    else {
        [self.placeholder drawInRect:rect
                            withFont:self.placeHolderFont
                       lineBreakMode:NSLineBreakByTruncatingTail
                           alignment:self.placeHolderTextAlignment];
    }

}

Upvotes: 12

Views: 6738

Answers (6)

giang.ngo
giang.ngo

Reputation: 45

Because you have set yourTextField.borderStyle = UITextBorderStyle....

Upvotes: 0

Gasper
Gasper

Reputation: 5689

Why not just shift the drawing rect and then invoke the super method implementation call? Swift code ensues...

override func drawPlaceholderInRect(rect: CGRect) {
    var newRect = CGRectInset(rect, 0, 2)
    newRect.origin.y += 2
    super.drawPlaceholderInRect(newRect)
}

Upvotes: 0

Steven Veltema
Steven Veltema

Reputation: 2150

A slight update

- (void) drawPlaceholderInRect:(CGRect)rect {
    if (self.useSmallPlaceholder) {
        NSDictionary *attributes = @{
                                 NSForegroundColorAttributeName : kInputPlaceholderTextColor,
                                 NSFontAttributeName : [UIFont fontWithName:kInputPlaceholderFontName size:kInputPlaceholderFontSize]
                                 };

        //center vertically
        CGSize textSize = [self.placeholder sizeWithAttributes:attributes];
        CGFloat hdif = rect.size.height - textSize.height;
        hdif = MAX(0, hdif);
        rect.origin.y += ceil(hdif/2.0);

        [[self placeholder] drawInRect:rect withAttributes:attributes];
    }
    else {
        [super drawPlaceholderInRect:rect];
    }
}

http://www.veltema.jp/2014/09/15/Changing-UITextField-placeholder-font-and-color/

Upvotes: 0

Muhammad Usman Aleem
Muhammad Usman Aleem

Reputation: 197

I have fixed this problem by subclassing UITextFieldClass and override drawPlaceholderInRect function.

 - (void)drawPlaceholderInRect:(CGRect)rect
{

    if(IS_IOS7)
    {
        [[self placeholder] drawInRect:CGRectMake(rect.origin.x, rect.origin.y+10, rect.size.width, rect.size.height) withFont:self.font];
    }
    else {

        [[self placeholder] drawInRect:rect withFont:self.font];
    }
}

Upvotes: 1

Vadoff
Vadoff

Reputation: 9419

drawInRect methods seem to behave differently in iOS7, you can try adding the following line and use that as the rect to draw instead. It's also backwards compatible with pre-iOS7.

  CGRect placeholderRect = CGRectMake(rect.origin.x, (rect.size.height- self.font.pointSize)/2, rect.size.width, self.font.pointSize);

Upvotes: 16

Marius Kažemėkaitis
Marius Kažemėkaitis

Reputation: 1973

The code bellow works on iOS 5/6/7

@implementation PlaceholderTextField

- (void)drawPlaceholderInRect:(CGRect)rect
{
    // Placeholder text color, the same like default
    UIColor *placeholderColor = [UIColor colorWithWhite:0.70 alpha:1];
    [placeholderColor setFill];

    // Get the size of placeholder text. We will use height to calculate frame Y position
    CGSize size = [self.placeholder sizeWithFont:self.font];

    // Vertically centered frame
    CGRect placeholderRect = CGRectMake(rect.origin.x, (rect.size.height - size.height)/2, rect.size.width, size.height);

    // Check if OS version is 7.0+ and draw placeholder a bit differently
    if (IS_IOS7) {

        NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
        style.lineBreakMode = NSLineBreakByTruncatingTail;
        style.alignment = self.textAlignment;
        NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:style,NSParagraphStyleAttributeName, self.font, NSFontAttributeName, placeholderColor, NSForegroundColorAttributeName, nil];

        [self.placeholder drawInRect:placeholderRect withAttributes:attr];


    } else {
        [self.placeholder drawInRect:placeholderRect
                            withFont:self.font
                       lineBreakMode:NSLineBreakByTruncatingTail
                           alignment:self.textAlignment];
    }

}

@end

Upvotes: 3

Related Questions