Text in UITextField moves up after editing (center while editing)
Asked Answered
I

13

45

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.

Idaidae answered 12/3, 2012 at 20:45 Comment(3)
Any progress on this? Seeing the same issue with my text fieldVolin
I am happy that I'm not the only one, I tried everything that I could think of... I will report any progress immediately, so keep checking this question :)Idaidae
@erkanyildiz yes you are right, i am second one who facing the same problem.....!!! well thanks for putting me on right track ..!!!!Inviolable
I
23

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

Idaidae answered 14/3, 2012 at 14:11 Comment(6)
I was also using a custom font. Strange. My solution was to update the fonts frame when the user stops updating to make sure it looked vertically centered.Volin
Happy to hear that it helped you :) (if you want you can vote my answer up) How did you update the fonts frame? Could you post some part of code? :) Thanks, DominikIdaidae
Instead of changing the font, try this. https://mcmap.net/q/374305/-using-a-custom-font-in-a-uitextfield-causes-it-to-shift-slightly-when-accessed-is-there-a-fixIndeterminate
@Indeterminate your answer is just one potential solution among others which only fixes one particular case (combination of font type, font size and UITextField height plus a bit of methods overriding). See my exhaustive answer below and you will see and learn other ways to fix this iOS glitch.Comestible
@Dominik Hadl the solution that you gave us is just a hack, it only works for one type of font and size, as soon as you change the font's size and/or the font's type the bug comes back. Thus it is not a solution which fixes all cases (combination of font type, font size and UITextField height), it's just a hack which temporary fixes the bug in one particular case. Other solutions to this problem would be as I mentioned below (see my answer) either decompiling and modifying the font and/or changing the font's type and/or the font size's and/or the UITextField's height in interface builder.Comestible
After hours of debugging, removing layout constraint, removing custom styling... found your post :) HelveticaNeue was the one that causes problem (in my case) Tx dude :) +1 UP ;)Ipswich
L
52

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
}
Limemann answered 7/10, 2015 at 15:35 Comment(5)
I met this too, I have company name, username, password as 3 UITextField in a row. But my symptom is not just on iOS 9, but also iOS 8. I doubt it is related to Xcode 7.0? Happens on iOS 8.3, 8.4 simulator as well. No 8.x device to test yet. But your solution works for both versions. that's why I think it is related to Xcode 7 or iOS 9 SDK.Pereyra
I had this issue when building for iOS 8 with Xcode 6. Before I got around to fixing it, I upgraded to Xcode 7 and starting building for iOS 9. And then I no longer saw the bug.Bauske
I experienced the same thing on iOS 9.0.2Monogamous
Same bug on iOS 9.0.2Purpura
Same bug on 10.1.1, come on Apple. BTW this fix still seems to work nicelyDupre
I
23

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

Idaidae answered 14/3, 2012 at 14:11 Comment(6)
I was also using a custom font. Strange. My solution was to update the fonts frame when the user stops updating to make sure it looked vertically centered.Volin
Happy to hear that it helped you :) (if you want you can vote my answer up) How did you update the fonts frame? Could you post some part of code? :) Thanks, DominikIdaidae
Instead of changing the font, try this. https://mcmap.net/q/374305/-using-a-custom-font-in-a-uitextfield-causes-it-to-shift-slightly-when-accessed-is-there-a-fixIndeterminate
@Indeterminate your answer is just one potential solution among others which only fixes one particular case (combination of font type, font size and UITextField height plus a bit of methods overriding). See my exhaustive answer below and you will see and learn other ways to fix this iOS glitch.Comestible
@Dominik Hadl the solution that you gave us is just a hack, it only works for one type of font and size, as soon as you change the font's size and/or the font's type the bug comes back. Thus it is not a solution which fixes all cases (combination of font type, font size and UITextField height), it's just a hack which temporary fixes the bug in one particular case. Other solutions to this problem would be as I mentioned below (see my answer) either decompiling and modifying the font and/or changing the font's type and/or the font size's and/or the UITextField's height in interface builder.Comestible
After hours of debugging, removing layout constraint, removing custom styling... found your post :) HelveticaNeue was the one that causes problem (in my case) Tx dude :) +1 UP ;)Ipswich
S
8

Disabling ClipsToBounds for the TextField solved it for me.

Stamper answered 22/11, 2016 at 3:44 Comment(2)
Your solution helped me. Could you explain why it works?Thorlay
My guess is that since the cursor is taller than the text and when you make the text field first responder and clips to bounds is enabled is must redraw the text to properly fit the text and cursor. What we are seeing is a redraw. When you disable clips to bounds you no longer constrain the vertical position of the textfield and therefore no redraw or update occurs. @hoseokchoiStamper
L
4

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.

Lassa answered 24/4, 2015 at 21:8 Comment(1)
This plus @n8tr's answer fixed a few other weird issues for me too. Recommend.Talos
C
2

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

Chateau answered 24/9, 2014 at 15:3 Comment(1)
Yes, that's true. Calculations with font size should also be used, but different fonts could have different offsetsChateau
C
1

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.

Comestible answered 23/12, 2014 at 9:33 Comment(7)
Could you explain why using insets and returning same frame for text/editingText/placeholder should fix issues? In most of my cases the problem is that the font renders incorrectly (moved) when returning same rects.Chateau
@GrizzlyNetch setting the insets is a fancy sentence meaning setting the paddings surrounding the text inside the UITextField. Here you can find a definition of the word inset: thefreedictionary.com/insetComestible
@GrizzlyNetch after that if it did not work for you on the first shot it is normal because as I said in my answer: this approach is "font dependant", values used for CGRectInset may vary for each font and size.Comestible
@GrizzlyNetch also for your information offset means margin.Comestible
I know it's font dependent. But for me I always needed to move the editingRect by certain offset (via CGRectOffset function)...and for the inset, it doesn't move the center of the "text" itself, it just adds horizontal padding (therefore my confusion - but I guess it's just an example).Chateau
The solution that you gave us is just a hack, it only works for one type of font and size, as soon as you change the font's size and/or the font's type the bug comes back. Thus it is not a solution which fixes all cases (combination of font type, font size and UITextField height), it's just a hack which temporary fixes the bug in one particular case. Other solutions to this problem would be either decompiling and modifying the font and/or changing the font's type and/or the font size's and/or the UITextField's height in interface builder.Vidrine
@Comestible your activity in this post is not aligned with Stack Overflow's ideal guidelines for being a good user. You have spammed almost every comment, which makes the valuable information in this post hard to find in-between all of your self-promoting spam. stackoverflow.com/help/behaviorSisterly
T
1

I fixed this by adding height constraints to my UITextFields.

Taboret answered 18/5, 2016 at 17:31 Comment(0)
B
0

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;
        }
}
Beaune answered 14/3, 2012 at 1:46 Comment(1)
Thanks for the answer :) I'm at work, will try it when I get home.Idaidae
A
0

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.

Antique answered 6/9, 2013 at 21:38 Comment(1)
The solution that you gave us is just a hack, it only works for one type of font and size, as soon as you change the font's size and/or the font's type the bug comes back. Thus it is not a solution which fixes all cases (combination of font type, font size and UITextField height), it's just a hack which temporary fixes the bug in one particular case. Other solutions to this problem would be as I mentioned above (see my answer) either decompiling and modifying the font and/or changing the font's type and/or the font size's and/or the UITextField's height in interface builder.Comestible
A
0

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!

Allomorph answered 2/2, 2016 at 4:1 Comment(0)
T
0

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];
}
Terhune answered 6/6, 2016 at 18:11 Comment(0)
F
0

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];
}
Forepeak answered 18/8, 2017 at 6:5 Comment(0)
E
0

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
}
Exemplificative answered 23/7, 2020 at 20:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.