简体   繁体   中英

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?

请改用以下内容:

[textfield setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];

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.

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)

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;

check the system version and return the UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(topPadding, leftPadding, 0, 0));

you can check device version as

if(([[[UIDevice currentDevice] systemVersion] floatValue]>=7.0))
{

}

i solved issue by using this property

textField.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;

It's working for both iOS6 and iOS7.

Ricky's solution worked for me with the addition this value has to be set each time AFTER placeholder text changed. I overwrote setPlaceholder to do that.

It replaces the need to overwrite drawPlaceholderInRect, if you want another placeholder color, therefore vertical alignment will be correct automatically. Of course this does not answer the question, why IOS 7.0 behaves like that, but it might solve your actual problem.

- (void) setPlaceholder: (NSString*)placeholderText {

    [super setPlaceholder:placeholderText];

    [self setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
}

It should be mentioned, that some people discourage this bypassing of public interfaces, so do it on your own risk! See also: Change UITextField's placeholder text color programmatically

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM