quicktype - Obtenir la hauteur du clavier iOS sans afficher le clavier



iphone cocoa-touch (2)

Une solution rapide que vous pourriez utiliser est la même que celle utilisée pour mettre en cache le clavier (la première fois que vous l'affichez, vous obtenez un léger retard ...). La bibliothèque est ici . Les bits intéressants:

[[[[UIApplication sharedApplication] windows] lastObject] addSubview:field];
[field becomeFirstResponder];
[field resignFirstResponder];
[field removeFromSuperview];

Donc, fondamentalement, c'est le montrer et ensuite le cacher. Vous pouvez écouter les notifications et juste obtenir la height sans réellement le voir. Bonus : vous arrivez à le mettre en cache. :)

https://src-bin.com

J'essaie d'obtenir la hauteur du clavier iOS. J'ai traversé et utilisé la méthode consistant à m'abonner à une notification telle que détaillée ici: https://gist.github.com/philipmcdermott/5183731

- (void)viewDidAppear:(BOOL) animated {
    [super viewDidAppear:animated];
    // Register notification when the keyboard will be show
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(keyboardWillShow:)
        name:UIKeyboardWillShowNotification
        object:nil];

    // Register notification when the keyboard will be hide
    [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(keyboardWillHide:)
        name:UIKeyboardWillHideNotification
        object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    CGRect keyboardBounds;

    [[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds];

    // Do something with keyboard height
}

- (void)keyboardWillHide:(NSNotification *)notification {
    CGRect keyboardBounds;

    [[notification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBounds];

    // Do something with keyboard height
}

Cela fonctionne très bien lorsque l'utilisateur affiche réellement le clavier.

Mon problème: J'ai une autre vue, appelons-la micView, qui peut être présentée avant l'apparition du clavier. L'utilisateur peut choisir d'utiliser le microphone avant de taper. Je voudrais que le micView ait la même hauteur que le clavier, c'est pourquoi j'ai besoin de la hauteur du clavier, mais j'en ai besoin avant que le clavier ne soit forcé d'apparaître. Ainsi, le UIKeyboardWillShowNotification n'est pas atteint avant que j'ai besoin de lire la valeur de la hauteur.

Ma question est: comment puis-je obtenir la hauteur du clavier à travers les notifications, ou une autre méthode sans jamais avoir le clavier apparaît.

J'ai considéré explicitement forcer le clavier à apparaître dans viewDidLoad, de sorte que je puisse définir une variable d'instance à cette valeur, puis la cacher et me débarrasser des animations pour les deux choses. Mais est-ce vraiment le seul moyen de le faire?


Answer #1

Cette classe Swift fournit une solution clé en main qui gère toutes les notifications et initialisations nécessaires, vous permettant d'appeler simplement une méthode de classe et d'avoir retourné la taille ou la hauteur du clavier.

Appel de Swift:

let keyboardHeight = KeyboardService.keyboardHeight()
let keyboardSize = KeyboardService.keyboardSize()

Appel à partir d'Objective-C:

 CGFloat keyboardHeight = [KeyboardService keyboardHeight];
 CGRect keyboardSize = [KeyboardService keyboardSize];

Si vous souhaitez l'utiliser pour la présentation d'affichage initiale, appelez ceci à partir de la méthode viewWillAppear d'une classe dans laquelle vous souhaitez viewWillAppear la hauteur ou la taille du clavier avant l'apparition du clavier. Il ne doit pas être appelé dans viewDidLoad, car une valeur correcte dépend de l'affichage de vos vues. Vous pouvez ensuite définir une constante de contrainte autolayout avec la valeur renvoyée par KeyboardService ou utiliser la valeur d'autres façons. Par exemple, vous voudrez peut-être obtenir la hauteur du clavier dans prepareForSegue pour aider à définir une valeur associée au contenu d'un containerView qui sera rempli via une section embarquée.

Remarque sur la zone de sécurité, la hauteur du clavier et l'iPhone X :
La valeur de la hauteur du clavier renvoie la hauteur totale du clavier qui, sur l'iPhone X, s'étend jusqu'au bord de l'écran lui-même, et pas seulement à l'encart de la zone de sécurité. Par conséquent, si vous définissez une valeur de contrainte de mise en forme automatique avec la valeur renvoyée, vous devez attacher cette contrainte au bord inférieur de la vue d'ensemble, et non à la zone de sécurité.

Remarque sur le clavier matériel dans le simulateur :
Lorsqu'un clavier matériel est connecté, ce code fournira la hauteur à l'écran de ce clavier matériel, c'est-à-dire sans hauteur. Bien entendu, cet état doit être pris en compte car cela simule ce qui se passera si vous avez un clavier matériel connecté à un périphérique réel. Par conséquent, votre mise en page qui attend une hauteur de clavier doit répondre de manière appropriée à une hauteur de clavier de zéro.

Classe KeyboardService:
Comme d'habitude, si vous appelez depuis Objective-C, il vous suffit d'importer l'en-tête de MyApp-Swift.h Swift de l'application, MyApp-Swift.h dans votre classe Objective-C.

import UIKit

class KeyboardService: NSObject {
    static var serviceSingleton = KeyboardService()
    var measuredSize: CGRect = CGRect.zero

    @objc class func keyboardHeight() -> CGFloat {
        let keyboardSize = KeyboardService.keyboardSize()
        return keyboardSize.size.height
    }

    @objc class func keyboardSize() -> CGRect {
        return serviceSingleton.measuredSize
    }

    private func observeKeyboardNotifications() {
        let center = NotificationCenter.default
        center.addObserver(self, selector: #selector(self.keyboardChange), name: .UIKeyboardDidShow, object: nil)
    }

    private func observeKeyboard() {
        let field = UITextField()
        UIApplication.shared.windows.first?.addSubview(field)
        field.becomeFirstResponder()
        field.resignFirstResponder()
        field.removeFromSuperview()
    }

    @objc private func keyboardChange(_ notification: Notification) {
        guard measuredSize == CGRect.zero, let info = notification.userInfo,
            let value = info[UIKeyboardFrameEndUserInfoKey] as? NSValue
            else { return }

        measuredSize = value.cgRectValue
    }

    override init() {
        super.init()
        observeKeyboardNotifications()
        observeKeyboard()
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }    
}

Head nod:
La méthode observerKeyboard basée ici sur l'approche originale décrite par Peres dans la réponse Objective-C à cette question.





keyboard