Brian Redman
Brian Redman

Reputation: 448

What's the proper way to dynamically resize a UITextField while keeping it centered as text is entered?

Given a textfield, I want it to dynamically resize horizontally as the user types in text. I also want it stay centered in its superview. I've stumbled on a way to do this but it seems contrived and unlikely to be the right approach. I feel like I'm missing something simple here like an attribute of a textfield or a control or some protocol I'm not familiar with.

In Interface Builder I have a UITextField with text "__". It has two constraints, 100 pixels from the top and centered vertically. The ViewController is the delegate for the textfield and the Editing Changed event is sent to textFieldAction:

- (IBAction)textFieldAction:(UITextField *)sender {
    NSString *s = sender.text;
    CGSize newSize = [sender sizeThatFits:CGSizeMake(MAXFLOAT, MAXFLOAT)];
    CGRect newFrame = sender.frame;
    newFrame.size = newSize;
    sender.frame = newFrame;
    sender.text = s;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    textField.text = @"";
    return YES;
}

The oddities are

In both cases the layout is eventually adjusted when the textfield resigns first responder.

Is this the right way to get a dynamically resizing and centered textfield, or a hack?

Upvotes: 1

Views: 495

Answers (1)

katzenhut
katzenhut

Reputation: 1742

It seems like a hack to me, but i cant test my own suggestion right now. If I tried to keep a textfield centered during the user input, i would use

-(BOOL)textField:(UITextField)shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

in the UITextFieldDelegate protocol and do the calculation there. While you are at it, you could also try [textfield sizeToFit] to get rid of the caculation altogether.

You could also get rid of the constraints and just set textfield.center.x = [[UIScreen mainScreen] screensize].width / 2 or textfield.center.x = textfield.superview.center.x to keep it centered horizontally. Or you stick with autolayout, im just not that big of a fan.

From the docs of textField:shouldChangeCharactersInRange:replacementString:

Return Value:  
YES if the specified text range should be replaced; otherwise, NO to keep the old text.

Discussion:  
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.`

So be sure to return YES, and let me know how it turns out if you try it.

Upvotes: 1

Related Questions