UITextField - (void)drawPlaceholderInRect:(CGRect)rect 在 iOS 7 中返回不同的 CGRect 高度

Posted

技术标签:

【中文标题】UITextField - (void)drawPlaceholderInRect:(CGRect)rect 在 iOS 7 中返回不同的 CGRect 高度【英文标题】:UITextField - (void)drawPlaceholderInRect:(CGRect)rect returns different CGRect height in iOS 7 【发布时间】:2013-09-25 19:05:42 【问题描述】:

我尝试继承 UITextField 来绘制自定义占位符。在ios 6 中这工作正常,但在iOS 7 中我得到了不同的CGRect 高度。

UITextField 框架是 (0, 0, 500, 45)。我通过覆盖添加了 20 的左填充 - (CGRect)editingRectForBounds:(CGRect)bounds;

- (CGRect)placeholderRectForBounds:(CGRect)bounds;

- (CGRect)textRectForBounds:(CGRect)bounds;

调用以下方法:

- (CGRect)makeRectFromBounds:(CGRect)bounds
              withTopPadding:(CGFloat)topPadding
              andLeftPadding:(CGFloat)leftPadding

    return UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(topPadding, leftPadding, 0, 0));


因为我想要不同的 placeHolder 文本颜色,所以我覆盖了

- (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];

我打印的矩形如下:

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)

知道这是一个错误还是我做错了什么?

【问题讨论】:

我遇到了同样的问题,对我来说最好的解决方案是:Set custom color and draw placeholder vertically centered on iOS 5/6/7 【参考方案1】:

改用以下内容:

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

【讨论】:

抱歉,我几天前匆匆忙忙赶来,专注于问题(不同的矩形大小),而不是更改颜色并让系统对齐。 但是,与这样的私有 API 混在一起还是很讨厌的。但我想这是一个 Objective-C 的“特性”。 这个应用商店安全吗? 是的。这没有问题。 很确定这与 iOS 8 中断了【参考方案2】:

在 iOS 7 中,contentVerticalAlignment 的默认值从“top”更改为“center”(我看不到任何文档)。在“中心”模式下,iOS 在绘制之前调整 rectForBounds 方法的结果。您可能应该在覆盖任何textRectForBounds 方法时设置contentVerticalAlignment = UIControlContentVerticalAlignmentTop,以便iOS 将完全按照指定使用矩形。

【讨论】:

试过了。就我而言,我需要它在中心,所以我将它设置为 UIControlContentVerticalAlignmentCenter 并且它仍然与顶部对齐。 能否将 contentVerticalAlignment 设置为“top”,然后在 textRectForBounds 中自行居中?如果它是顶部对齐的,我认为 iOS 会使用你给它的任何 rect;如果它是中心对齐的,它只需要改变。 @Cyupa,我面临同样的问题。你有什么解决办法吗? @Roshni 嗨,不。我无法找到对这种行为的合乎逻辑的、记录在案的解释。如果检查 UIDevice 单例上的 systemVersion 属性,则解决方案很糟糕。我对此并不满意,但在我找到真正的原因之前,它会起作用。【参考方案3】:

由于iOS7现在是新的,所以很多人都面临iOS7的框架问题。

对于他们所有人,我只想说这很简单,iOS7 没有任何问题。只是因为您不知道如何从 Apple 提供的最新操作系统功能中获益。

@Cyupa :您只需要应用自动调整大小并屏蔽您的文本字段。

可能是以下一项或多项。

UIViewAutoresizingFlexibleBottomMargin UIViewAutoresizingFlexibleTopMargin UIViewAutoresizingFlexibleLeftMargin UIViewAutoresizingFlexibleRightMargin UIViewAutoresizingFlexibleHeight UIViewAutoresizingFlexibleWidth

如果您对文本字段应用适当的 autosizingmask,您将获得所需的视图框架(此处为文本字段)

【讨论】:

感谢您的建议,但没有效果。我很欣赏你的想法,而且一开始就没有教过它。可悲的是,它没有帮助。【参考方案4】:

我也遇到了这个问题,还没找到原因,但是如果你想在iOS6和iOS7上都有相同的行为,你可以试试这个:

- (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;

你可能需要设置:

theLabel.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;

【讨论】:

【参考方案5】:

检查系统版本并返回UIEdgeInsetsInsetRect(bounds, UIEdgeInsetsMake(topPadding, leftPadding, 0, 0));

您可以检查设备版本为

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



【讨论】:

是的,我知道这一点,但我不会将其称为解决方案,因为操作系统返回不同的值。我正在寻找为什么 CGRect 在 iOS 7 中不同的逻辑解释。无论如何,谢谢。 同样,我也想知道真正的底层问题,并避免像这样在整个代码中进行零散的修复。 Rick 的建议是正确的,但我急于解决问题,而不是我对 UITextField 的期望。它仍然很奇怪,但它解决了我的问题,改变了占位符文本颜色。【参考方案6】:

我通过使用这个属性解决了问题

textField.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;

它适用于 iOS6 和 iOS7。

【讨论】:

【参考方案7】:

Ricky 的解决方案对我有用,并且每次更改占位符文本后都必须设置此值。我重写了 setPlaceholder 来做到这一点。

它取代了覆盖drawPlaceholderInRect的需要,如果你想要另一种占位符颜色,因此垂直对齐将自动正确。当然,这并不能回答问题,为什么 IOS 7.0 会这样,但它可能会解决您的实际问题。

- (void) setPlaceholder: (NSString*)placeholderText 

    [super setPlaceholder:placeholderText];

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

应该提到的是,有些人不鼓励这种绕过公共接口的做法,所以这样做需要您自担风险! 也可以看看: Change UITextField's placeholder text color programmatically

【讨论】:

不,它不起作用,我试过了,即使很艰难,我也不相信它真的会起作用。占位符颜色与占位符框架有什么关系? 正如您自己写的那样:“因为我想要不同的 placeHolder 文本颜色,所以我覆盖了 drawPlaceholderInRect”。这就是联系。如果你不覆盖它,垂直对齐将是正确的,不管 contentVerticalAlignment - 至少只要你不覆盖其他函数,这可能会弄乱矩形(例如,对于你的左填充)。如果您认为我对您撒谎,说它对我有用,和/或我不知道我在说什么,请也投反对票。 哦,我现在明白了。对于那个很抱歉。我很困惑,我专注于问题(矩形大小)而不是我首先关注的问题:更改占位符文本颜色。所以我会给你解释的赏金,我必须道歉。谢谢您的帮助。但我必须给 Ricky 正确的答案,因为他是第一个,我也和他一起像个傻瓜一样冲进来。

以上是关于UITextField - (void)drawPlaceholderInRect:(CGRect)rect 在 iOS 7 中返回不同的 CGRect 高度的主要内容,如果未能解决你的问题,请参考以下文章

UITextField 方法和代理的使用

ios开发 uitextfield 怎么判断输入的汉字

UITextField 监听数值变化的三种方法

iOS开发:检测UITextField文本框的状态

UITextfield 键盘辞职

UITextField点击选中文字