UIKeyboardBoundsUserInfoKey est obsolète, ce qu'il faut utiliser à la place?

je travaille sur une application iPad en utilisant 3.2 sdk. J'essaie d'obtenir la taille du clavier pour empêcher mes textfields de se cacher derrière.

je reçois un avertissement dans Xcode - > UIKeyboardBoundsUserInfoKey est déprécié que devrais-je utiliser à la place pour ne pas recevoir cet avertissement?

49
demandé sur Meet Doshi 2010-05-11 04:28:14

8 réponses

j'ai joué avec la solution proposée précédemment mais j'avais encore des problèmes. Voici ce que j'ai trouvé à 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];
}
87
répondu Jay 2012-08-16 15:36:46

De la documentation pour UIKeyboardBoundsUserInfoKey :

la touche pour un objet NSValue contenant un CGRect qui identifie les limites du rectangle du clavier en coordonnées de fenêtre. Cette valeur est suffisante pour obtenir la taille du clavier. Si vous voulez obtenir l'origine du clavier sur l'écran (avant ou après l'animation) utilisez les valeurs obtenues du dictionnaire d'information utilisateur à travers le Uikeyboardcenterbeginuserinfokey ou uikeyboardcenterenduserinfokey constantes. utilisez la touche UIKeyboardFrameBeginUserInfoKey ou UIKeyboardFrameEndUserInfoKey à la place.

Apple recommande la mise en œuvre d'une routine de commodité comme celle-ci (qui pourrait être mise en œuvre en tant qu'ajout de catégorie à 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 les propriétés de la taille du cadre du clavier ajustée à la fenêtre.

j'ai adopté une approche différente, qui consiste à vérifier l'orientation du dispositif:

CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;
55
répondu Alex Reynolds 2012-05-02 20:45:58

il vous suffit d'utiliser 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];
9
répondu iOS_User 2011-01-05 06:45:17

le code suivant corrige un problème dans la réponse de Jay , qui suppose que UIKeyboardWillShowNotification ne tirera pas à nouveau lorsque le clavier est déjà présent.

en tapant avec le clavier japonais / chinois, iOS lance un UIKeyboardWillShowNotification supplémentaire avec le nouveau cadre de clavier même si le clavier est déjà présent, conduisant à la hauteur du self.textView être réduit une deuxième fois dans le code original.

This réduit self.textView à presque rien. Il devient alors impossible de se remettre de ce problème puisque nous n'attendons qu'un seul UIKeyboardWillHideNotification la prochaine fois que le clavier est rejeté.

au lieu de soustraire/ajouter de la hauteur à self.textView selon que le clavier est affiché/caché comme dans le code original, le code suivant calcule simplement la hauteur maximale possible pour self.textView après avoir soustrait la hauteur du clavier à l'écran.

cela suppose que self.textView est supposé remplir la vue entière du contrôleur de vue, et il n'y a pas d'Autre 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 d'enregistrer les notifications clavier dans 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];
}

Sur le fractionnement du redimensionnement de code en deux parties

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

étant donné que le clavier est déjà présent avant que le contrôleur de vue ne soit poussé, il n'y a aucune notification de clavier supplémentaire générée par iOS, et donc aucun moyen de redimensionner le textView basé sur ces notifications de clavier.

Le code ci-dessus (ainsi que le code original) qui redimensionne self.textView ne fonctionnera donc que lorsque le clavier est affiché après la vue a été chargée.

ma solution est de créer un singleton qui stocke les dernières coordonnées du clavier, et sur - viewDidAppear: du viewController, appelez:

- (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 cela dans - viewWillAppear: , cependant d'après mon expérience (à au moins sur iOS 6), la méthode convertRect:fromView: que nous devons utiliser dans resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: ne convertit pas correctement le cadre du clavier en coordonnées de vue avant que la vue soit entièrement visible.

3
répondu junjie 2017-05-23 10:27:45

utilisez simplement la touche UIKeyboardFrameBeginUserInfoKey ou UIKeyboardFrameEndUserInfoKey au lieu de UIKeyboardBoundsUserInfoKey

2
répondu Anand Mishra 2012-10-05 07:49:41

@Jason, vous codez si bien sauf pour un point.

pour le moment vous n'animez rien et la vue va simplement " pop " à sa nouvelle taille.hauteur.

vous devez spécifier un État à partir duquel animer. Une animation est une sorte de (de l'etat)->(pour l'état).

heureusement il y a une méthode très pratique pour spécifier l'état actuel de la vue comme l'état (from).

[UIView setAnimationBeginsFromCurrentState:YES];

si vous ajoutez cette ligne juste après beginAnimations:context: votre code fonctionne parfaitement.

1
répondu Thomas 2010-06-22 09:39:14
- (CGSize)keyboardSize:(NSNotification *)aNotification {
    NSDictionary *info = [aNotification userInfo];
    NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    CGSize keyboardSize;
    if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) {
        _screenOrientation = orientation;
        if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize = [beginValue CGRectValue].size;
        } else {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        }
    } else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) {
        // We didn't rotate
        if (_screenOrientation == orientation) {
            if (UIDeviceOrientationIsPortrait(orientation)) {
                keyboardSize = [beginValue CGRectValue].size;
            } else {
                keyboardSize.height = [beginValue CGRectValue].size.width;
                keyboardSize.width = [beginValue CGRectValue].size.height;
            }
        // We rotated
        } else if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        } else {
            keyboardSize = [beginValue CGRectValue].size;
        }
    }


    return keyboardSize;
}
1
répondu Cameron Lowell Palmer 2011-03-07 10:32:02