Dominik Hadl
Dominik Hadl

Reputation: 3619

Text in UITextField moves up after editing (center while editing)

I have a strange problem. I have an UITextField in which the user should write the amount of something, so the field is called "amountField". Everything looks fine, when the user starts editing the textfield the text is in the vertical and horizontal center - that's great.

However, when the user ends editing the text moves up a little bit. I tried many things, nothing helped...

I am adding screenshots below, so you can see what is the problem.

This is what it looks like while editing the field - that's ok.

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

And this is how it looks when done editing - that is the problem!

This is the problem.

Please, if anybody know what could cause this I would be very grateful! :)

Here is some of my code related to the 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: Those white corners are there because I set the background to white with 0.2 alpha, that's ok.

Upvotes: 45

Views: 19275

Answers (13)

landnbloc
landnbloc

Reputation: 1068

I used this extension. Only problem was I didn't add translatesAutoresizingMaskIntoConstraints = true before I called it. Ah silly goose

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
}

Upvotes: 0

rollingstoneW
rollingstoneW

Reputation: 1

These solution above doesn't work for me.My solution is subclass UITextField and override setText:

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

Upvotes: 0

Alexis Candelaria
Alexis Candelaria

Reputation: 257

Disabling ClipsToBounds for the TextField solved it for me.

Upvotes: 8

kdvijay
kdvijay

Reputation: 1

This is because the BaselineOffset for the textfield got changed. In UITextFieldDidEndEditing creating an attributed text with NSBaselineOffset: 0 and using that attributedText would fix the problem.

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

Upvotes: 0

skr1p7k1dd
skr1p7k1dd

Reputation: 109

This bug happened to me when I set text & became the first responder in viewDidLoad or viewWillAppear. When I moved the becomeFirstResponder code to viewDidAppear the bug went away.

Upvotes: 4

Christopher Garcia
Christopher Garcia

Reputation: 2544

I fixed this by adding height constraints to my UITextFields.

Upvotes: 1

Gilbertat
Gilbertat

Reputation: 1

Check the keyboard to change the view of the position of the pop-up if there is line of code self.view.layoutIfNeeded() Delete it.Good Luck!

Upvotes: 0

Brian Palma
Brian Palma

Reputation: 641

I had similar issues with a UITextfield embedded in a UITableViewCell. Where exactly is this code located in your project? What I believe is happening is that after you've finished editing a particular textfield, it sends itself -setNeedsDisplay and its drawRect: is subsequently called. This might explain the shift in alignment. In my particular scenario, I had to use a table view delegate method -willDisplayCell... to set the content alignment. I would have to know more about your design to possibly offer a suggestion.

One potential solution would be to use the text field delegate methods to set the content alignment.

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

Upvotes: 0

n8tr
n8tr

Reputation: 5066

I had a similar issue that started happening on iOS 9. Basically I have a UITextField in a collection view cell. Sometimes when the user is done typing and editing ends, the text "bounces" up then down again into its correct position. Very strange and annoying glitch. Simply making this tweak fixed the issue on iOS 9 and proved to be safe on iOS 7 and 8:

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

Upvotes: 52

King-Wizard
King-Wizard

Reputation: 15694

There is a glitch on iOS 8.1 and below, I do not know if they will fix it later but at that time there is not an unique solution which fixes all cases, because the bug and the solutions are font's type, size dependent.

One of this solution or a combination of these solutions below can fix your problem:

  • Changing the font's size.

  • Changing the font's type.

  • Changing the UITextField's size.

  • Decompiling the font in question, modifying the font's characteristics and recompiling it (for more explanation please consult the following links: link 1 and link 2).

Otherwise this other self-sufficient solution below can fix your problem:

Swift version

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))
    }

}

This solution has been tested with leftView and works like a charm.

NOTE: this approach is "font dependant", values used for CGRectInset may vary for each font and size.

Upvotes: 1

JakubKnejzlik
JakubKnejzlik

Reputation: 6483

I'm struggling with this issue almost every time when the design of app is with custom font. One option is to fix the font (but this is too much work – at least for me :) ). The second option I'm using is subclassing the UITextField and overriding the editingRectForBounds: and placeholderRectForBounds: methods and correct the offset. It should work for your case too.

@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

I haven't tested it with leftView or rightView though, so be careful when using these :)

NOTE: this approach is "font dependant", values used for offset may vary for each font and size

Upvotes: 2

Dominik Hadl
Dominik Hadl

Reputation: 3619

So...

After many hours of trying many things - I have found the problem. In my case the problem is the font. I really don't know why, but the author of the font made the font weird (leading etc.), it has a blank space on the bottom. I don't know why, but when you are editing the text all of the text properties are ignored, but after you finish editing, they are applied.

So, if you have a similar problem, try changing the font to Arial or something similar.

For a full explanation, please consult these following links: link 1 and link 2. The solution recommended in these links can avoid you a lot of headaches and can even be applied to fix problem like text moving to the top when you start editing an UITextField (using System font or other particular fonts).

Upvotes: 23

Zak Arntson
Zak Arntson

Reputation: 382

I wasn't able to change the font file, so when I solved this I saved the original UITextField's frame in a property and applied the following code:

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

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

It's a bit hacky, but it gets the job done.

Upvotes: 0

Related Questions