UITextField: move view when keyboard appears

后端 未结 7 1308
心在旅途
心在旅途 2020-11-29 16:32

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

7条回答
  •  孤城傲影
    2020-11-29 17:02

    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).

提交回复
热议问题