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.

Dominik Hadl
  • 3,609
  • 3
  • 24
  • 58
  • 1
    Any progress on this? Seeing the same issue with my text field – Steven Baughman Mar 14 '12 at 00:27
  • 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 :) – Dominik Hadl Mar 14 '12 at 08:33
  • @erkanyildiz yes you are right, i am second one who facing the same problem.....!!! well thanks for putting me on right track ..!!!! – Kamar Shad Feb 09 '13 at 09:26

13 Answers13

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
}
n8tr
  • 5,018
  • 2
  • 32
  • 33
  • 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. – Wingzero Oct 16 '15 at 07:11
  • 1
    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. – peacetype Oct 17 '15 at 00:37
  • I experienced the same thing on iOS 9.0.2 – wasabi Oct 20 '15 at 20:12
  • 1
    Same bug on iOS 9.0.2 – pronebird Oct 21 '15 at 14:19
  • 3
    Same bug on 10.1.1, come on Apple. BTW this fix still seems to work nicely – bfich Nov 11 '16 at 20:42
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).

lorenz
  • 4,538
  • 1
  • 27
  • 45
Dominik Hadl
  • 3,609
  • 3
  • 24
  • 58
  • 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. – Steven Baughman Mar 14 '12 at 17:31
  • 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, Dominik – Dominik Hadl Mar 14 '12 at 18:47
  • 6
    Instead of changing the font, try this. http://stackoverflow.com/a/10087220/244183 – McDJ Apr 10 '12 at 10:43
  • @McDJ 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. – King-Wizard Dec 24 '14 at 09:43
  • @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. – King-Wizard Dec 24 '14 at 09:47
  • 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 ;) – zvjerka24 Jun 26 '15 at 15:30
8

Disabling ClipsToBounds for the TextField solved it for me.

  • Your solution helped me. Could you explain why it works? – alanhchoi May 07 '17 at 14:57
  • 2
    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. @hoseokchoi – Alexis Candelaria May 08 '17 at 07:58
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.

iGatiTech
  • 2,306
  • 1
  • 21
  • 45
skr1p7k1dd
  • 109
  • 2
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

JakubKnejzlik
  • 6,363
  • 3
  • 40
  • 41
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.

King-Wizard
  • 15,628
  • 6
  • 82
  • 76
  • 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. – JakubKnejzlik Dec 25 '14 at 11:25
  • @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: http://www.thefreedictionary.com/inset – King-Wizard Dec 25 '14 at 13:18
  • @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. – King-Wizard Dec 25 '14 at 13:21
  • @GrizzlyNetch also for your information offset means margin. – King-Wizard Dec 25 '14 at 13:23
  • 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). – JakubKnejzlik Dec 25 '14 at 19:12
  • 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. – Blacky Dec 22 '15 at 15:05
  • @King-Wizard 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. http://stackoverflow.com/help/behavior – jungledev Jun 02 '16 at 17:22
1

I fixed this by adding height constraints to my UITextFields.

Christopher Garcia
  • 2,536
  • 7
  • 30
  • 40
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.

Zak Arntson
  • 372
  • 2
  • 8
  • 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. – King-Wizard Dec 24 '14 at 09:47
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!

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];
}
iGatiTech
  • 2,306
  • 1
  • 21
  • 45
kdvijay
  • 1
  • 2
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];
}
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
}
landnbloc
  • 498
  • 4
  • 10
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;
        }
}
Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Brian Palma
  • 641
  • 1
  • 7
  • 13