2013-04-16 4 views
10

Je réalise qu'il existe de nombreuses solutions similaires, telles que TPKeyboardAvoiding, Apple's famous solution, et diverses suggestions impliquant l'utilisation de UIScrollView. Dans mon cas, j'ai besoin de redimensionner une vue pour accommoder le clavier plutôt que de le faire défiler ou de le déplacer. This solution se rapproche le plus de ce que j'essaie d'atteindre, donc c'était ma base. Cependant, j'ai un problème à faire fonctionner les choses en mode paysage. Ma méthode qui redimensionne la vue lorsque le clavier apparaît est la suivante:Redimensionner une vue lorsqu'un clavier apparaît (iOS)

- (void)keyboardWillShow:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; 

    CGRect keyboardFrame = [[self textField].superview convertRect:[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; 
    CGRect statusBarFrame = [[self textField].superview convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil]; 

    CGRect bounds = [self textField].superview.bounds;  
    CGRect newFrame = CGRectMake(0.0, 0.0, bounds.size.width, keyboardFrame.origin.y + statusBarFrame.size.height); 
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     [self textField].superview.frame = newFrame; 
    } completion:nil]; 
} 

Ceci fonctionne parfaitement en mode portrait.

enter image description here

Cependant, en mode paysage, la vue redimensionne de gauche à droite ou de droite à gauche en fonction de la direction dans laquelle le dispositif a été mis en rotation, plutôt que de bas en haut.

enter image description here

Manifestement, il y a quelque chose de mal avec la façon dont je l'aide de coordonnées, et un cadre de référence est pas ce que je pense qu'il est en mode paysage, mais je vais avoir un mal fou trier comment le résoudre. J'ai essayé de convertir toutes sortes de choses avec -convertRect: mais rien que j'essaie ne m'amène nulle part. J'espere vraiment quelqu'un qui est moins confus par tous ces rectangles et comment ils changent quand les changements d'orientation peuvent repérer ce que je fais mal et ce que je dois faire pour bien faire les choses. Pour référence, j'ai created a project montrant le cas le plus simple qui reproduit le problème que j'ai.

+0

Vous souhaitez activer l'iPan lorsque le clavier est visible? –

+0

Idéalement, oui, puisque je suis sûr que certains utilisateurs le feront. Mais je pense que si je peux faire fonctionner cette solution (j'ajoute une méthode quand le clavier est caché pour redimensionner la vue), cela fonctionnera automatiquement. Je crois que lorsqu'un périphérique est pivoté avec le clavier affiché, iOS envoie successivement les notifications keyboardWillHide et keyboardWillShow. – bkocik

+0

Merci pour le code d'animation, très pratique. – phatmann

Répondre

26

Je ne vous conseille pas de redimensionner la vue racine pour votre contrôleur de vue, vous pouvez créer contentView et ajouter à la vue du contrôleur de vue. Vous pouvez modifier la taille de ce contenu comme ci-dessous (je n'utilise pas de mise en page automatique):

- (void)keyboardWillShow:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil]; 

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y); 
    } completion:nil]; 
} 

- (void)keyboardWillHide:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil]; 

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y); 
    } completion:nil]; 
} 
+0

Merci beaucoup! Le redimensionnement de ma vue racine était mon seul problème? (A part le fait de ne pas me retirer en tant qu'observateur sur dealloc et de ne pas avoir le code à utiliser pour cacher le clavier, je les ai dans l'application actuelle. – bkocik

+0

Maintenant l'application est très simple donc difficile de parler de plus de problèmes :). Dans les futurs problèmes possibles, vous pouvez toujours résoudre ici. –

+0

Cela m'a sauvé tellement de maux de tête ... merci beaucoup! –

-1

Essayez ces méthodes. Modifiez-le en fonction de vos besoins.

#define kOFFSET_FOR_KEYBOARD 280.0 

- (void)keyboardWillHide:(NSNotification *)notif { 
    [self setViewMoveUp:NO]; 
} 


- (void)keyboardWillShow:(NSNotification *)notif{ 
    [self setViewMoveUp:YES]; 
} 


- (void)textFieldDidBeginEditing:(UITextField *)textField { 
    stayup = YES; 
    [self setViewMoveUp:YES]; 
} 


- (void)textFieldDidEndEditing:(UITextField *)textField { 
    stayup = NO; 
    [self setViewMoveUp:NO]; 
} 

//method to move the view up/down whenever the keyboard is shown/dismissed 
-(void)setViewMoveUp:(BOOL)moveUp 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view 
    [UIView setAnimationBeginsFromCurrentState:YES]; 

    CGRect rect = self.view.frame; 
    if (moveUp) 
    { 
     // 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. 

     if (rect.origin.y == 0) { 
      rect.origin.y -= kOFFSET_FOR_KEYBOARD; 
      //rect.size.height += kOFFSET_FOR_KEYBOARD; 
     } 

    } 
    else 
    { 
     if (stayup == NO) { 
      rect.origin.y += kOFFSET_FOR_KEYBOARD; 
      //rect.size.height -= kOFFSET_FOR_KEYBOARD; 
     } 
    } 
    self.view.frame = rect; 
    [UIView commitAnimations]; 
} 
+0

Merci, mais cela déplace la vue - j'ai besoin de redimensionner le mien - et par une valeur codée en dur; Je préfère trouver la taille de leur clavier à l'exécution pour l'avenir. – bkocik

1

je l'avais fait espérons que ce code sera helpfull pour u.

- (void)viewWillAppear:(BOOL)animated 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillShow:) 
               name:UIKeyboardWillShowNotification 
               object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillBeHidden:) 
               name:UIKeyboardWillHideNotification 
               object:nil]; 
} 

- (void)keyboardWillShow:(NSNotification*)notification 
{ 
    [self moveControls:notification up:YES]; 
} 

- (void)keyboardWillBeHidden:(NSNotification*)notification 
{ 
    [self moveControls:notification up:NO]; 
} 

- (void)moveControls:(NSNotification*)notification up:(BOOL)up 
{ 
    NSDictionary* userInfo = [notification userInfo]; 
    CGRect newFrame = [self getNewControlsFrame:userInfo up:up]; 

    [self animateControls:userInfo withFrame:newFrame]; 
} 

- (CGRect)getNewControlsFrame:(NSDictionary*)userInfo up:(BOOL)up 
{ 
    CGRect kbFrame = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; 
    kbFrame = [self.view convertRect:kbFrame fromView:nil]; 

    CGRect newFrame = self.view.frame; 
    newFrame.origin.y += kbFrame.size.height * (up ? -1 : 1); 

    return newFrame; 
} 

- (void)animateControls:(NSDictionary*)userInfo withFrame:(CGRect)newFrame 
{ 
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    [UIView animateWithDuration:duration 
          delay:0 
         options:animationOptionsWithCurve(animationCurve) 
        animations:^{ 
         self.view.frame = newFrame; 
        } 
        completion:^(BOOL finished){}]; 
} 

static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve) 
{ 
    return (UIViewAnimationOptions)curve << 16; 
} 
+0

Beaucoup d'efforts, mais cette réponse a été répondue il y a deux ans. Pour faire un meilleur usage de vos compétences, vous pouvez regarder la liste des questions récentes sur vos tags. http://stackoverflow.com/questions/tagged/iphone?sort=newest&pageSize=30 –

+0

Ok merci beaucoup –

5

La réponse de Vitaliy B est rapide. J'ai une vue appelée templateHeaderContentView, j'ai créé une fonction et j'ai configuré la hauteur de la vue. Vous utilisez votre propre vue et modifiez la hauteur en conséquence.

func keyboardWillShow(notification: NSNotification) { 
    keyboardShowOrHide(notification) 
} 

func keyboardWillHide(notification: NSNotification) { 
    keyboardShowOrHide(notification) 
} 

private func keyboardShowOrHide(notification: NSNotification) { 
    guard let userInfo = notification.userInfo else {return} 
    guard let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]else { return } 
    guard let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] else { return } 
    guard let keyboardFrameEnd = userInfo[UIKeyboardFrameEndUserInfoKey] else { return } 

    let curveOption = UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)) 
    let keyboardFrameEndRectFromView = view.convertRect(keyboardFrameEnd.CGRectValue, fromView: nil) 
    UIView.animateWithDuration(duration.doubleValue ?? 1.0, 
     delay: 0, 
     options: [curveOption, .BeginFromCurrentState], 
     animations: {() -> Void in 
      self.templateHeaderContentView.configureView(keyboardFrameEndRectFromView.origin.y) 
     }, completion: nil) 
} 
+0

J'ai utilisé la réponse de Vitaily, mais pensez à inclure la fonction configureView pour la postérité;) – Greg

Questions connexes