Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField - (void)drawPlaceholderInRect:(CGRect)rect returns different CGRect height in iOS 7

I tried to subclass UITextField to draw custom placehoder. In iOS 6 this works fine but in iOS 7 I got a different CGRect height.

The UITextField frame is (0, 0, 500, 45). I added a left padding of 20 by overriding - (CGRect)editingRectForBounds:(CGRect)bounds;

- (CGRect)placeholderRectForBounds:(CGRect)bounds;

- (CGRect)textRectForBounds:(CGRect)bounds;

Calling the method below to do so:

- (CGRect)makeRectFromBounds:(CGRect)bounds
              withTopPadding:(CGFloat)topPadding
              andLeftPadding:(CGFloat)leftPadding
{
    return UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(topPadding, leftPadding, 0, 0));

}

Because I want a different placeHolder text color, I override

- (void)drawPlaceholderInRect:(CGRect)rect

- (void)drawPlaceholderInRect:(CGRect)rect {

    [[UIColor colorWithRed:121.0/255.0
                     green:113.0/255.0
                      blue:107.0/255.0
                     alpha:1.0] setFill];

    [self printRect:rect from:__FUNCTION__];

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

The rectangle I'm printing is the following:

iOS 7: -Rect (X: 0.0, Y:0.0, W:480.0, H:44.0)

iOS 6: -Rect (X: 0.0, Y:0.0, W:480.0, H:26.0)

Any idea if this is a bug or am I doing something wrong?

like image 533
Cyupa Avatar asked Sep 20 '13 11:09

Cyupa


4 Answers

Use the following instead:

[textfield setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
like image 138
Ricky Avatar answered Nov 14 '22 05:11

Ricky


In iOS 7 the default value for contentVerticalAlignment changed from "top" to "center" (with no documentation that I could see). In "center" mode iOS adjusts the result of the rectForBounds methods before drawing into them. You should probably set contentVerticalAlignment = UIControlContentVerticalAlignmentTop when overriding any of textRectForBounds methods so iOS will use the rect exactly as specified.

like image 23
Ben Darnell Avatar answered Nov 14 '22 05:11

Ben Darnell


Since iOS7 is new nowadays, so many people faces framing issue with iOS7.

To all of them, I just want say that it is so easy and there isn't any issue with iOS7. It's just because you don't know how to take benefits from the latest OS feature provided by Apple.

@Cyupa : You just need to apply autosizing and mask your textfield.

it could be one or more from following.

  • UIViewAutoresizingFlexibleBottomMargin
  • UIViewAutoresizingFlexibleTopMargin
  • UIViewAutoresizingFlexibleLeftMargin
  • UIViewAutoresizingFlexibleRightMargin
  • UIViewAutoresizingFlexibleHeight
  • UIViewAutoresizingFlexibleWidth

if you apply proper autosizingmask to your textfield, you will get your desired frame for your view (Here textfield)

like image 24
Niru Mukund Shah Avatar answered Nov 14 '22 05:11

Niru Mukund Shah


I also met this problem, not found why yet, but if you want to have the same behavior on both iOS6 and iOS7, you can try this:

- (CGRect)textRectForBounds:(CGRect)bounds {
    CGRect rect = [super textRectForBounds:bounds];
    rect = CGRectMake(20, rect.origin.y-4, rect.size.width-20, rect.size.height);
    return rect;
}

and you may need to set:

theLabel.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;
like image 26
user2765993 Avatar answered Nov 14 '22 03:11

user2765993