49 votes

Xcode / iOS5: Déplacer UIView vers le haut, lorsque le clavier apparaît

Je voudrais passer à mon avis, lorsque le clavier est affiché. Le clavier (hauteur : 216) devrait pousser vers le haut de mon avis avec sa hauteur. Est-ce possible avec un code simple ?

97voto

djromero Points 11713

Pour déplacer la vue up, il suffit de changer son center. Tout d'abord, de garder celui d'origine en CGPoint de la propriété.

- (void)viewDidLoad 
{
    ...
    self.originalCenter = self.view.center;
    ...
}

Ensuite, modifiez au besoin, lorsque le clavier s'affiche:

self.view.center = CGPointMake(self.originalCenter.x, /* new calculated y */);

Enfin, restaurer lorsque le clavier est caché:

self.view.center = self.originalCenter;

Ajouter de l'animation de sucre que vous le souhaitez

Vous avez plus qu'un seul moyen de savoir quand le clavier s'affiche.

L'observation UIKeyboardDidShowNotification de notification.

/* register notification in any of your initWithNibName:bundle:, viewDidLoad, awakeFromNib, etc. */
{
    ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];     
    ...
}

- (void)keyboardDidShow:(NSNotification *)note 
{
    /* move your views here */
}

Faire le contraire avec UIKeyboardDidHideNotification.

-OU-

Mettre En Œuvre UITextFieldDelegate

Détecter lors de l'édition de début/fin pour déplacer les vues autour.

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{
    /* keyboard is visible, move views */
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    /* resign first responder, hide keyboard, move views */
}

Selon les champs de texte, vous pouvez avoir besoin de suivre dans le champ est à l'utilisateur de les modifier, ajouter une minuterie pour éviter de déplacer les points de vue trop.

31voto

Tendulkar Points 4299

procédez comme suit. après le clavier visible, utilisez ce code

13voto

Michael Points 622

Je l'ai fait dans un mode similaire à djromero sauf que j'ai ajusté le cadre de l'origine de la vue plutôt que de son centre.

Le point de vue que je suis en mouvement est un UIScrollView, et je veux qu'il à déplacer par rapport à un objet UITextField élément, de sorte que le champ de texte affiche toujours. La position de ce champ de texte peut varier en fonction du décalage de défilement de la vue.

Donc, mon code ressemble à ceci:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
    return YES;
}

- (NSInteger)getKeyBoardHeight:(NSNotification *)notification
{
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
    NSInteger keyboardHeight = keyboardFrameBeginRect.size.height;
    return keyboardHeight;
}

-(void) keyboardDidShow:(NSNotification*) notification
{
    NSInteger keyboardHeight;
    keyboardHeight = [self getKeyBoardHeight:notification];
    NSInteger scrollViewFrameHeight = self.scrollView.frame.size.height;
    NSInteger textFieldRelativePosition = self.tableView.frame.origin.y - self.scrollView.contentOffset.y;
    NSInteger textFieldFrameOffset = scrollViewFrameHeight - textFieldRelativePosition;
    NSInteger movement = MAX(0,keyboardHeight-textFieldFrameOffset); // Offset from where the keyboard will appear.
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,-movement,
                                           self.scrollView.frame.size.width,
                                           self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
}

La vue-contrôleur est un UITextFieldDelegate et adhère également à UIKeyboardDidShowNotification de sorte que nous sommes en mesure d'accéder à la taille du clavier.

Lorsque le clavier montre, nous calculons l'offset relatif de l'objet UITextField (ajusté pour faire défiler offset) et le clavier et changer l'origine de la UIScrollView sorte qu'elle se déplace juste assez pour que l'objet UITextField encore à l'affiche.

Si l'objet UITextField affichera toujours, même si le clavier s'affiche, puis l'origine ne change pas.

13voto

Kaushik Points 24

C'est le moyen le plus simple et le plus efficace d'y parvenir:

Ajoutez les constantes suivantes:

 static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;    
 

Ajoutez ceci à votre contrôleur de vue:

 CGFloat animatedDistance;
 

Et ajoutez ces méthodes à votre code:

 - (void)textFieldDidBeginEditing:(UITextField *)textField{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
    heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
    heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
    orientation == UIInterfaceOrientationPortraitUpsideDown)
{
    animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
    animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}

- (void)textFieldDidEndEditing:(UITextField *)textfield{

CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}
 

5voto

Rockfire Points 38

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X