51 votes

UIKeyboardBoundsUserInfoKey est obsolète, que faut-il utiliser à la place?

Je travaille sur une application iPad en utilisant le sdk 3.2. Je fais face à obtenir la taille du clavier pour empêcher mon textfields de hidding derrière elle.

Je reçois un avertissement dans Xcode-> UIKeyboardBoundsUserInfoKey est déconseillé que dois-je utiliser plutôt ne pas à obtenir cet avertissement ?

87voto

Jay Points 1296

J'ai joué avec la solution précédemment proposée mais j'avais toujours des problèmes. Voici ce que je suis venu à la place:

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

    - (void)keyboardWillHide:(NSNotification *)aNotification {
        [self moveTextViewForKeyboard:aNotification up:NO]; 
    }

- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
NSDictionary* userInfo = [aNotification userInfo];

// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;

CGRect keyboardEndFrame;

[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];


[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];


// Animate up or down
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];

CGRect newFrame = textView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];

newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1);
textView.frame = newFrame;

[UIView commitAnimations];
}
 

57voto

Alex Reynolds Points 45039

À partir de la documentation pour UIKeyboardBoundsUserInfoKey:

La clé pour un NSValue objet contenant une CGRect qui identifie les limites du rectangle du clavier dans la fenêtre de coordonnées. Cette valeur est suffisante pour l'obtention de la taille du clavier. Si vous souhaitez obtenir de l'origine du clavier à l'écran (avant ou après l'animation) utiliser les valeurs obtenues à partir des infos de l'utilisateur du dictionnaire par le biais de la UIKeyboardCenterBeginUserInfoKey ou UIKeyboardCenterEndUserInfoKey constantes. Utiliser le UIKeyboardFrameBeginUserInfoKey ou UIKeyboardFrameEndUserInfoKey clé à la place.

Apple recommande la mise en œuvre d'une commodité de routine comme cela (ce qui pourrait être mis en œuvre comme une catégorie plus UIScreen):

+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
    UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
    return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}

pour récupérer fenêtre ajusté clavier cadre de la taille des propriétés.

J'ai pris une approche différente, qui consiste à vérifier l'orientation du périphérique:

CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;

9voto

iOS_User Points 757

Vous utilisez simplement ce code:

 //NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//instead of Upper line we can use either next line or nextest line.
//NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
 

3voto

junjie Points 770

Le code suivant résout un problème dans de Jay réponse, qui suppose qu' UIKeyboardWillShowNotification ne se déclenche pas à nouveau lorsque le clavier est déjà présent.

Lors de la saisie avec le Chinois/Japonais clavier, iOS déclenche un extra - UIKeyboardWillShowNotification avec le nouveau clavier de l'image même si le clavier est déjà présent, conduisant à la hauteur de l' self.textView réduit une deuxième fois dans le code d'origine.

Cela réduit self.textView à presque rien. Il devient alors impossible de les récupérer à partir de ce problème, car nous ne prévoyons un seul UIKeyboardWillHideNotification la prochaine fois que le clavier est rejeté.

Au lieu de soustraire/ajout de la hauteur d' self.textView selon que le clavier est affiché/caché comme dans le code d'origine, le code suivant calcule le maximum de hauteur pour self.textView après la soustraction de la hauteur du clavier à l'écran.

Cela suppose qu' self.textView est supposé remplir la totalité de l'affichage de la vue-contrôleur, et il n'y a pas d'autres sous-vue qui doit être visible.

- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif {

    NSDictionary* userInfo = [notif userInfo];
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrameInWindowsCoordinates;

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates];

    [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates
                             withAnimationDuration:animationDuration
                                    animationCurve:animationCurve];

}

- (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates
                           withAnimationDuration:(NSTimeInterval)duration
                                  animationCurve:(UIViewAnimationCurve)curve
{

    CGRect fullFrame = self.view.frame;

    CGRect keyboardFrameInViewCoordinates =
    [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];

    // Frame of the keyboard that intersects with the view. When keyboard is
    // dismissed, the keyboard frame still has width/height, although the origin
    // keeps the keyboard out of the screen.
    CGRect keyboardFrameVisibleOnScreen =
    CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates);

    // Max frame availble for text view. Assign it to the full frame first
    CGRect newTextViewFrame = fullFrame;

    // Deduct the the height of any keyboard that's visible on screen from
    // the height of the text view
    newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height;

    if (duration)
    {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:duration];
        [UIView setAnimationCurve:curve];
    }

    // Adjust the size of the text view to the new one
    self.textView.frame = newTextViewFrame;

    if (duration)
    {
        [UIView commitAnimations];
    }

}

Aussi, n'oubliez pas de vous inscrire le clavier notifications dans le viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter];

    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil];
    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil];
}

A propos du fractionnement du redimensionnement de code en deux parties

La raison pour laquelle le textView redimensionnement code est divisé en deux parties (resizeTextViewWithKeyboardNotification: et resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:) est de fixer un autre problème lorsque le clavier persiste à travers une poussée à partir d'un point de vue contrôleur à l'autre (voir Comment puis-je détecter le clavier iOS quand elle reste entre les contrôleurs?).

Comme le clavier est déjà présent avant que le contrôleur est poussé, il n'y a pas de clavier supplémentaire de notifications générées par iOS, et donc aucun moyen de redimensionner l' textView basés sur ceux du clavier notifications.

Le code ci-dessus (ainsi que le code d'origine) qui se redimensionne self.textView seulement de travail lorsque le clavier est affiché après le point de vue a été chargé.

Ma solution est de créer un singleton qui stocke la dernière clavier coordonnées, et sur l' - viewDidAppear: de la viewController, composez le:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Resize the view if there's any keyboard presence before this
    // Only call in viewDidAppear as we are unable to convertRect properly
    // before view is shown
    [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame]
                         withAnimationDuration:0
                                animationCurve:0];
}

UASKeyboard est mon singleton ici. Idéalement, nous devrions appeler cette en - viewWillAppear:, mais dans mon expérience (au moins sur iOS 6), l' convertRect:fromView: méthode que nous avons besoin d'utiliser en resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: ne pas convertir correctement le clavier de l'image à l'affichage des coordonnées avant le point de vue est entièrement visible.

2voto

andy12 Points 333

Il suffit d’utiliser la ou clés au lieu de``

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