I have 6 Textfields in my viewController. 2 on the first row, 1 on the second, 1 on the third and 2 on the last row. The textfields work fine as far as typing into it. I just have issues scrolling the view up and down when the keyboard appears. The view scrolls up fine but when I "resign responder", the view scrolls down but scrolls down too much. e.g. if the view moved up by y amount, once I resign responder, the view would move down a value greater than y.
I have the following code set up (I've provided extra code just in case but I believe the problem is in setViewMovedUp method, but I may be wrong):
Keyboard showing:
-(void)keyboardWillShow:(NSNotification*)sender {
// Animate the current view out of the way
NSDictionary* info = [sender userInfo];
kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (!didViewMove) {
didViewMove = YES;
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
}
-(void)keyboardWillHide {
[UIView animateWithDuration:0.25 animations:^{
self.view.frame = CGRectMake(0, _top, 320, self.view.frame.size.height);
}];
return;
didViewMove = NO;
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
Adjusting the View
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // slide up the view
int desiredHeight = (480 - kbSize.height) / 2;
int requiredHeightAdjustment;
if (didViewMove) {
requiredHeightAdjustment = abs(desiredHeight - (self.view.frame.origin.y + activeField.frame.origin.y));
} else {
requiredHeightAdjustment = abs(desiredHeight - (activeField.frame.origin.y ));
// requiredHeightAdjustment = abs(desiredHeight - (self.view.frame.origin.y + activeField.frame.origin.y));
}
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= requiredHeightAdjustment;
rect.size.height += requiredHeightAdjustment;
}
else
{
// revert back to the normal state.
rect.origin.y += requiredHeightAdjustment;
rect.size.height -= requiredHeightAdjustment;
}
self.view.frame = rect;
[UIView commitAnimations];
}
Resigning Responder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([_cardnumbertext isFirstResponder] && [touch view] != _cardnumbertext) {
[_cardnumbertext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
UITouch *touch1 = [[event allTouches] anyObject];
if ([_salesamounttext isFirstResponder] && [touch1 view] != _salesamounttext) {
[_salesamounttext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
UITouch *touch2 = [[event allTouches] anyObject];
if ([_referencetext isFirstResponder] && [touch2 view] != _referencetext) {
[_referencetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
UITouch *touch3 = [[event allTouches] anyObject];
if ([_datetext isFirstResponder] && [touch3 view] != _datetext) {
[_datetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
UITouch *touch4 = [[event allTouches] anyObject];
if ([_timetext isFirstResponder] && [touch4 view] != _timetext) {
[_timetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
UITouch *touch5 = [[event allTouches] anyObject];
if ([_reasontext isFirstResponder] && [touch5 view] != _reasontext) {
[_reasontext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}
and lastly, setting up active fields
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
previousField = activeField;
}