Keyboard up before view up

Asked

Viewed 348 times

0

As the statement says, As soon as I touch one input the keyboard goes up and then the view goes up. I’d like to know what I’m doing wrong.

PS: In addition, between the keyboard and the view, there is a black space and the scroll view still works, thus making it even uglier with the effect.

#pragma mark - UITextField Delegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSString *guestlistName = [alertView textFieldAtIndex:0].text;

    if (buttonIndex == 1) // Cancel
        return;

    if (guestlistName == nil || [guestlistName length] == 0)
        return;
}

// Keyboard handling junk below
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillBeHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];
}

 - (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;

    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        [self.scrollView scrollRectToVisible:activeField.frame animated:YES];
    }
}

- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
 UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;

}

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

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

- (void) textViewDidBeginEditing:(UITextView *)textView {
activeField = textView;
}

- (void) textViewDidEndEditing:(UITextView *)textView {
    activeField = textView;
}

- (void) dismissKeyboard {
    [activeField resignFirstResponder];
}

Thanks in Advance!

2 answers

1

I made an example using Swift, but the footprint is more or less the same.

You can also choose to animate the Uiviewcontroller view as a whole as follows:

Attributes:

@IBOutlet weak var search: UITextField!
var isKeyboardLifted: Bool = false

Viewwillappear

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    var center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
    center.addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    center.addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)

    var tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
    self.view.addGestureRecognizer(tap)
}

Methods of selectors

// MARK: UITextFieldDelegate
// Selector do keyboardWillShow
func keyboardWillShow(notification: NSNotification) {
    var info: NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()

    var keyboardHeight: CGFloat = keyboardSize.height

    if (!isKeyboardLifted) {
        self.isKeyboardLifted = true
        UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in
            self.view.frame = CGRectMake(0, (self.view.frame.origin.y - keyboardHeight), self.view.bounds.width, self.view.bounds.height)
        }, completion: nil)
    }
}

// Selector do keyboardWillHide
func keyboardWillHide(notification: NSNotification) {
    var info: NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()

    var keyboardHeight: CGFloat = keyboardSize.height

    if (isKeyboardLifted) {
        self.isKeyboardLifted = false
        UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in
            self.view.frame = CGRectMake(0, (self.view.frame.origin.y + keyboardHeight), self.view.bounds.width, self.view.bounds.height)
        }, completion: nil)
    }
}

// Selector do UIGesture
func dismissKeyboard() {
    self.search.endEditing(true)
}

0

It is possible to make this shift with or without system notifications. It has happened to me of UIKeyboardDidShowNotification and UIKeyboardWillShowNotification generate a delay that would prevent offset animation from being compatible with keyboard input animation. If this is happening to you do it this way:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    //Deixar o scrollView maior permite que o usuário role a página até o fim sem precisar esconder o teclado.
    self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width, self.scrollView.frame.size.height + kbSize.height);

    //No método "viewDidLoad" da respectiva classe, valorize uma variável global 'tamanhoDeslocamentoTeclado' com o valor 0.
    tamanhoDeslocamentoTeclado = 0;

    CGRect frameRelativo = [textField convertRect:textField.bounds toView:self.scrollView];

    //DISTANCIA_TECLADO_PROXIMA é um define onde você escolhe a qual distância do textField/textView o teclado deve ficar. Entre 8.0 e 15.0, por exemplo. 
    int alturaIdeal = self.view.frame.size.height - (kbSize.height) - textField.frame.size.height - DISTANCIA_TECLADO_PROXIMA;

    if(frameRelativo.origin.y > alturaIdeal)
    {
        tamanhoDeslocamentoTeclado = frameRelativo.origin.y - alturaIdeal;
    }

    if(tamanhoDeslocamentoTeclado!=0)
    {
        [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut
                     animations:^{self.scrollView.contentOffset = CGPointMake(0, tamanhoDeslocamentoTeclado);}
                     completion:nil];
    }
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    //No método "viewDidLoad" da respectiva classe, valorize uma variável global 'tamanhoOriginalScroll' com o tamanho original do scrollView. Este tamanho é o que o componente ocupa quando não há teclado nenhum na tela.

    if(tamanhoDeslocamentoTeclado!=0)
    {
        [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut
                     animations:^{self.scrollView.contentOffset = CGPointMake(0, 0);self.scrollView.contentSize = tamanhoOriginalScroll;}
                     completion:nil];
   }
}

It is possible that your scrollView is inside another view container (or several others), in which case you need to know the position of the scrollView relative to the base view of the parent viewController. This shift is more advanced because it requires an extra control variable, but I believe it is not your case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.