1

I am trying to get my textfield(s) to expand horizontally while the user types. I have the code:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    CGFloat textWidth = [[NSString stringWithFormat:@"%@%@",[textField text], string] sizeWithFont:[textField font]].width;
    textWidth += 15;
    CGRect tFFrame = [textField frame];

    tFFrame.size.width = textWidth;
    textField.frame = tFFrame;

    [textField setNeedsDisplay];
    return YES;


}

Which works for most cases, but at first backspace the frame doesn't update, and when I paste when text is already selected, it acts like replaced text was still there. How can I fix these issues, and also, I know that the sizeWithFont: method is not for iOS 7, so it anyone has any ideas on how to make backwards compatibility, that would also be great.

Thanks in advance.

Minebomber
  • 1,209
  • 2
  • 12
  • 35

1 Answers1

1

You aren't processing the changes properly. You need something like this:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];

    CGFloat textWidth = [newText sizeWithFont:[textField font]].width;
    textWidth += 15;
    CGRect tFFrame = [textField frame];

    tFFrame.size.width = textWidth;
    textField.frame = tFFrame;

    [textField setNeedsDisplay];
    return YES;
}

This change will properly handle a user typing regardless of caret position and text selection as well as cuts and pastes in the text field.

Your original code always assumed the user was adding the new text to the end and that no text was selected at the time.

sizeWithFont: was replaced by sizeWithAttributes: in iOS 7. A little searching will show plenty of existing questions covering that topic.

Community
  • 1
  • 1
rmaddy
  • 314,917
  • 42
  • 532
  • 579