编辑后UITextField中的文本向上移动(编辑时居中)

时间:2012-03-12 20:45:41

标签: iphone objective-c ios xcode uitextfield

我有一个奇怪的问题。我有一个UITextField,用户应在其中写入一些内容,因此该字段称为“amountField”。一切都很好看,当用户开始编辑文本字段时,文本位于垂直和水平中心 - 这很棒。

然而,当用户结束编辑时,文本会向上移动一点点。我尝试了很多东西,没有任何帮助...

我在下面添加了截图,因此您可以看到问题所在。

这是编辑字段时的样子 - 没关系。

This is while editing the field - that's ok.

这就是完成编辑后的样子 - 即问题

This is the problem.

如果有人知道可能导致这种情况的话,我将非常感激! :)

以下是与amountField相关的一些代码。

amountField.keyboardType = UIKeyboardTypeNumberPad;
amountField.returnKeyType = UIReturnKeyDone;
amountField.delegate = self;

[amountField setFont:[UIFont fontWithName:@"Nuptial Script LT Std" size:30]];   
amountField.borderStyle = UITextBorderStyleNone;
UIImage *amountBg = [UIImage imageNamed:@"skin2_ipad_amountField.png"];
[amountField setBackground:amountBg];

amountField.rightView = nil;
//amountField.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.2];

amountField.textAlignment = UITextAlignmentCenter;
amountField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
amountField.adjustsFontSizeToFitWidth = YES;
amountLabel.textColor = UIColorFromARGB(0x313030); //Using my own macro

amountField.frame = CGRectMake(300, 480, 136, 32);
amountField.center = CGPointMake(605, 439);

PS:那些白角是因为我将背景设置为白色,带有0.2 alpha,这没关系。

13 个答案:

答案 0 :(得分:51)

我有一个类似的问题开始在 iOS 9 上发生。基本上我在集合视图单元格中有一个UITextField。有时,当用户完成输入和编辑结束时,文本“反弹”然后再次向下进入其正确位置。非常奇怪和烦人的故障。只需进行此调整即可解决iOS 9上的问题,并证明在iOS 7和8上是安全的:

 - (void)textFieldDidEndEditing:(UITextField *)textField
 {
    [textField layoutIfNeeded]; //Fixes iOS 9 text bounce glitch
    //...other stuff
}

答案 1 :(得分:23)

因此...

经过几个小时尝试很多事情 - 我发现了问题。 在我的情况下,问题是字体。我真的不知道为什么,但字体的作者使字体怪异(领先等),它底部有一个空白区域。我不知道为什么,但是当您编辑文本时,所有文本属性都会被忽略,但在完成编辑后,它们会被应用。

因此,如果您遇到类似问题,请尝试将字体更改为Arial或类似字体。

有关完整说明,请参阅以下链接:link 1link 2。这些链接中推荐的解决方案可以避免很多麻烦,甚至可以应用于修复当您开始编辑UITextField(使用系统字体或其他特定字体)时移动到顶部的文本等问题。

答案 2 :(得分:8)

禁用TextField的ClipsToBounds为我解决了这个问题。

答案 3 :(得分:3)

当我设置文本&成为viewDidLoadviewWillAppear中的第一个响应者。当我将becomeFirstResponder代码移到viewDidAppear时,错误消失了。

答案 4 :(得分:2)

我几乎每次使用自定义字体设计应用时都会遇到这个问题。一种选择是修复字体(但这是太多的工作 - 至少对我来说:))。我正在使用的第二个选项是继承UITextField并覆盖editingRectForBounds:和placeholderRectForBounds:方法并更正偏移量。它也适用于你的情况。

@implementation MyTextFieldWithFixedFontPosition

-(CGRect)editingRectForBounds:(CGRect)bounds{
    return CGRectOffset([self textRectForBounds:bounds], 0, 0.5); //0.5 is just example, you can adjust to any offset you like
}
-(CGRect)placeholderRectForBounds:(CGRect)bounds{
    return [self editingRectForBounds:bounds];
}

@end

我还没有使用leftView或rightView测试它,所以在使用这些时要小心:)

注意:此方法与字体相关",用于偏移的值可能因字体和大小而异

答案 5 :(得分:1)

我通过向UITextFields添加高度限制来修复此问题。

答案 6 :(得分:0)

我在UITextfield中嵌入UITableViewCell时出现过类似问题。这段代码到底在哪里?我相信正在发生的事情是,在您完成特定文本字段的编辑后,它会自行发送-setNeedsDisplay并随后调用其drawRect:。这可能解释了一致性的转变。在我的特定场景中,我不得不使用表视图委托方法-willDisplayCell ...来设置内容对齐。我需要了解更多有关您的设计的信息,以便提出建议。

一种可能的解决方案是使用文本字段委托方法来设置内容对齐。

-(void)textFieldDidEndEditing:(UITextField *)textField{
     if (amountField == textField){
          amountField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
        }
}

答案 7 :(得分:0)

我无法更改字体文件,因此当我解决此问题时,我将原始UITextField的框架保存在属性中并应用以下代码:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    textField.frame = self.usernameFrame;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    textField.frame = CGRectOffset(self.usernameFrame, 0, 1);
}

这有点笨拙,但它完成了工作。

答案 8 :(得分:0)

iOS 8.1及以下版本有一个小故障,我不知道他们是否会稍后修复它,但当时并没有一个解决所有情况的独特解决方案,因为bug和解决方案都是字体的类型,尺寸依赖。

此解决方案之一或以下这些解决方案的组合可以解决您的问题:

  • 更改字体的大小。

  • 更改字体的类型。

  • 更改UITextField的大小。

  • 反编译相关字体,修改字体的特征并重新编译(有关详细说明,请参阅以下链接:link 1link 2)。< /强>

否则,下面的其他自给自足的解决方案可以解决您的问题:

Swift版本

import UIKit

class CustomTextField: UITextField {

    ...

    override func textRectForBounds(bounds: CGRect) -> CGRect {
        // Possible values.
        return CGRectInset(bounds, CGFloat(35.0), CGFloat(0.0))
    }

    override func editingRectForBounds(bounds: CGRect) -> CGRect {
        // Possible values.
        return CGRectInset(bounds, CGFloat(35.0), CGFloat(0.0))
    }

    override func placeholderRectForBounds(bounds: CGRect) -> CGRect {
        // Possible values.
        return CGRectInset(bounds, CGFloat(35.0), CGFloat(0.0))
    }

}

此解决方案已经过使用leftView测试,并且像魅力一样。

注意:此方法与字体有关&#34;,用于CGRectInset的值可能因字体和大小而异。

答案 9 :(得分:0)

如果有代码行self.view.layoutIfNeeded()删除它,请检查键盘以更改弹出窗口位置的视图。祝你好运!

答案 10 :(得分:0)

这是因为文本字段的BaselineOffset已更改。 在UITextFieldDidEndEditing中使用NSBaselineOffset创建一个属性文本:0并使用attributedText来解决问题。

-(IBAction)txtFieldDidEndEditing:(UITextField *)sender {
     NSDictionary *style = @{
                            NSBaselineOffsetAttributeName: @(0)
                            };
    self.txtField.attributedText = [[NSAttributedString alloc] initWithString:self.txtField.text attributes:style];
}

答案 11 :(得分:0)

上面的这些解决方案对我来说不起作用。我的解决方案是子类UITextField并覆盖setText:

- (void) setText:(NSString *)text {
    [super setText:text];
    [self layoutIfNeeded];
}

答案 12 :(得分:0)

我使用了这个扩展名。唯一的问题是我在调用它之前未添加translatesAutoresizingMaskIntoConstraints = true。傻鹅

func centerVertically() {
    textContainerInset = UIEdgeInsets.zero
    textContainer.lineFragmentPadding = 5
    let fittingSize = CGSize(width: bounds.width, height: 
     CGFloat.greatestFiniteMagnitude)
    let size = sizeThatFits(fittingSize)
    let topOffset = (bounds.size.height - size.height * zoomScale) / 2
    let positiveTopOffset = max(1, topOffset)
    contentOffset.y = -positiveTopOffset
}