Reputation: 3619
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.
And this is how it looks when done editing - that 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
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
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
Reputation: 257
Disabling ClipsToBounds for the TextField solved it for me.
Upvotes: 8
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
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
Reputation: 2544
I fixed this by adding height constraints to my UITextFields.
Upvotes: 1
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
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
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
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
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
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
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