|
Mar 25
|
When you develop forms or any screens with input fields, occasionally the inputs will be obscured by the keyboard when it appears. This is bad usability for the user who now has to input data without being able to see what they have typed! One solution is to slide the whole view so that the field being edited is always visible.



This solution I provide adds a few methods to UIView (yes i know, adding categories to cocoa classes is naughty) – which will determine how much to slide the view based on the inputs position on the whole screen, and then slide the view at the same speed as the keyboard slide entry. It then will slide back to where it was when you are finished editing.
It is pretty simple to do this – here is how I calculate where to scroll the view:
- (void) maintainVisibityOfControl:(UIControl *)control offset:(float)offset {
static const float deviceHeight = 480;
static const float keyboardHeight = 216;
static const float gap = 5; //gap between the top of keyboard and the control
//Find the controls absolute position in the 320*480 window - it could be nested in other views
CGPoint absolute = [control.superview convertPoint:control.frame.origin toView:nil];
//If it would be hidden behind the keyboard....
if (absolute.y > (keyboardHeight + gap)) {
//Shift the view
float shiftBy = (deviceHeight - absolute.y) - (deviceHeight - keyboardHeight - gap - offset);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f]; //this is speed of keyboard
CGAffineTransform slideTransform = CGAffineTransformMakeTranslation(0.0, shiftBy);
self.transform = slideTransform;
[UIView commitAnimations];
}
}
..and then I reset the view afterwards using:
- (void) resetViewToIdentityTransform {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f]; //this is speed of keyboard
CGAffineTransform slideTransform = CGAffineTransformIdentity;
self.transform = slideTransform;
[UIView commitAnimations];
}
You only need to make minimal changes to your own code, and call these methods from your UITextFieldDelegate methods (or other control delegates):
- (void) textFieldDidBeginEditing:(UITextField *)textField {
[self.view maintainVisibityOfControl:textField offset:0.0f];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == currentControl) {
//If the textfield is still the same one, we can reset the view animated
[self.view resetViewToIdentityTransform];
}else {
//However, if the currentControl has changed - that indicates the user has
//gone into another control - so don't reset view, otherwise animations jump around
}
}
Here is a copy of the XCode project:

Thanks