views:

1716

answers:

2

Hello!

I'm currently working on an iPhone application with a single view, which has multiple UITextFields for input. When the keyboard shows, it overlays the bottom textfields. So I added the corresponding textFieldDidBeginEditing: method, to move the view up, which works great:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    if ( ( textField != inputAmount ) && ( textField != inputAge ) ) {
     NSTimeInterval animationDuration = 0.300000011920929;
     CGRect frame = self.view.frame;
     frame.origin.y -= kOFFSET_FOR_KEYBOARD;
     frame.size.height += kOFFSET_FOR_KEYBOARD;
     [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
     [UIView setAnimationDuration:animationDuration];
     self.view.frame = frame;
     [UIView commitAnimations];  
    }
}

This method checks, if the source of the message is one of the textfields that are visible when the keyboard shows, and if not, it moves the view up.

I also added the textFieldDidEndEnditing: method, which moves the view down again (and updates some model objects according to the changed input):

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ( ( textField != inputMenge ) && ( textField != inputAlter ) ) {
     NSTimeInterval animationDuration = 0.300000011920929;
     CGRect frame = self.view.frame;
     frame.origin.y += kOFFSET_FOR_KEYBOARD;
     frame.size.height -= kOFFSET_FOR_KEYBOARD;
     [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
     [UIView setAnimationDuration:animationDuration];
     self.view.frame = frame;
     [UIView commitAnimations];  
    }
    // Additional Code
}

However, this solution has a simple flaw: When I finish editing one of the "hidden" textfields and touch another textfield, the keyboard vanishes, the view moves down, the view moves up again and the keyboard reappears.

Is there any possibility to keep the keyboard from vanishing and reappearing between two edits (of the "hidden" textfields - so that the view only moves when the selected textfield changes from one that would be hidden by the keyboard to one that would not be hidden)?

+4  A: 

I just solved this problem. The solution is a combination of a UIKeyboardDidShowNotification and UIKeyboardDidHideNotification observer with the above textFieldDidBeginEditing: and textFieldDidEndEditing: methods.

You need three additional variables, one to store the current selected UITextField (which I have named activeField), one to indicate if the current view has been moved, and one to indicate if the keyboard is displayed.

This is how the two UITextField delegate methods look now:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    activeField = nil;
    // Additional Code
}

When the view is loaded, the following two observers are created:

- (void)viewDidLoad {
    // Additional Code
    [[NSNotificationCenter defaultCenter] addObserver:self
               selector:@selector(keyboardWasShown:)
                name:UIKeyboardDidShowNotification
                 object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
               selector:@selector(keyboardWasHidden:)
                name:UIKeyboardDidHideNotification
                 object:nil];
}

And the corresponding methods are implemented as follows:

- (void)keyboardWasShown:(NSNotification *)aNotification {
    if ( keyboardShown )
     return;

    if ( ( activeField != inputAmount ) && ( activeField != inputAge ) ) {
     NSDictionary *info = [aNotification userInfo];
     NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
     CGSize keyboardSize = [aValue CGRectValue].size;

     NSTimeInterval animationDuration = 0.300000011920929;
     CGRect frame = self.view.frame;
     frame.origin.y -= keyboardSize.height-44;
     frame.size.height += keyboardSize.height-44;
     [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
     [UIView setAnimationDuration:animationDuration];
     self.view.frame = frame;
     [UIView commitAnimations];

     viewMoved = YES;
    }

    keyboardShown = YES;
}

- (void)keyboardWasHidden:(NSNotification *)aNotification {
    if ( viewMoved ) {
     NSDictionary *info = [aNotification userInfo];
     NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
     CGSize keyboardSize = [aValue CGRectValue].size;

     NSTimeInterval animationDuration = 0.300000011920929;
     CGRect frame = self.view.frame;
     frame.origin.y += keyboardSize.height-44;
     frame.size.height -= keyboardSize.height-44;
     [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
     [UIView setAnimationDuration:animationDuration];
     self.view.frame = frame;
     [UIView commitAnimations];

     viewMoved = NO;
    }

    keyboardShown = NO;
}

This code works now as expected. The keyboard is only dismissed when the Done button is pressed, otherwise it stays visible and the view is not moved around.

As an additional note, I think it is possible to get the animationDuration dynamically by asking the NSNotification object, since I have already played with a similar solution but didn't get it to work (which it does now).

ComSubVie
Which files did which pieces of code go in?
Jacob Lyles
A: 

Thanks it works for me..

i did the same way for TextView

Prabu Somasunaram