Thursday, November 12, 2009

Moving UITextFields over the keyboard without a UIScrollView

I had a UIViewController with a couple of UITextFields attached to its default UIView and everything was fine. Later on, I added a couple more text fields, so I had to make sure all text fields are displayed properly when the keyboard shows up. I thought about using a UIScrollView or maybe a UITableView which scrolls naturally, but I thought I didn't have to change my controller just for that. I found these 2 posts [1, 2] on stackoverflow pretty useful, but I still had to tweak the code a little and here's what I got:

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[activeField resignFirstResponder];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
activeField = textField;
[self setViewMovedUp:YES];
return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[activeField resignFirstResponder];
[self setViewMovedUp:NO];
activeField = nil;
return YES;
}

- (void)setViewMovedUp:(BOOL)movedUp {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];

CGRect viewFrame = self.view.frame;
CGRect textFieldFrame = [activeField convertRect:[activeField bounds] toView:self.view];

if (movedUp) {
viewFrame.origin.y = -textFieldFrame.origin.y/1.8;
} else {
viewFrame.origin.y = 0;
}
self.view.frame = viewFrame;

[UIView commitAnimations];
}

Let me explain a couple of things here, first: activeField is a UIControl* instance variable I added to my UIVeiwController. second: you can replace (textFieldFrame.origin.y/1.8) with any function of (textFieldFrame.origin.y) that would do the job. Maybe you can try assigning certain offsets for each range of y values, but I preferred this neat form and the result was neat too.

No comments: