Comment détecter de manière fiable si un clavier externe est connecté sur iOS 9?
avant iOS 9, la méthode la plus fiable pour déterminer si un clavier externe est connecté était d'écouter UIKeyboardWillShowNotification
et de faire un champ de texte le premier répondant, comme discuté dans cette question . La notification se déclencherait lorsqu'on utilise le clavier virtuel, mais pas lorsqu'on utilise un clavier externe.
cependant ce comportement a changé avec iOS 9. UIKeyboardWillShowNotification
s'allume aussi lorsqu'un clavier externe est connecté, puisque la nouvelle barre d'outils du clavier est maintenant affichée.
il est encore possible de détecter la hauteur du clavier et de juger si c'est la barre d'outils plus petite ou le clavier virtuel plus grand qui est affiché. Cependant, cette méthode n'est pas fiable puisque la hauteur du clavier a changé entre les différents beta et ne peut pas être comptée pour rester la même au fil du temps.
Existe-t-il une méthode plus fiable qui puisse être utilisée avec iOS 9?
6 réponses
après être retourné à la question originale, j'ai trouvé une solution qui fonctionne.
il semble que lorsque le clavier virtuel habituel est affiché, le cadre du clavier se trouve dans les dimensions de l'écran. Toutefois, lorsqu'un clavier physique est connecté et que la barre d'outils du clavier est affichée, le cadre du clavier est situé hors écran. Nous pouvons vérifier si le cadre du clavier est hors écran pour déterminer si la barre d'outils du clavier est affichée.
- (void) keyboardWillShow:(NSNotification *)notification
{
NSDictionary* userInfo = [notification userInfo];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboard = [self.view convertRect:keyboardFrame fromView:self.view.window];
CGFloat height = self.view.frame.size.height;
if ((keyboard.origin.y + keyboard.size.height) > height) {
self.hasKeyboard = YES;
}
}
ce code prend en charge iOS 8 et iOS 9, inputAccessoryView, a une constante à double protection pour être prêt à de nouvelles modifications dans les futures versions de iOS et de prendre en charge de nouveaux appareils:
#define gThresholdForHardwareKeyboardToolbar 160.f // it's minimum height of the software keyboard on non-retina iPhone in landscape mode
- (bool)isHardwareKeyboardUsed:(NSNotification*)keyboardNotification {
NSDictionary* info = [keyboardNotification userInfo];
CGRect keyboardEndFrame;
[[info valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
float height = [[UIScreen mainScreen] bounds].size.height - keyboardEndFrame.origin.y;
return height < gThresholdForHardwareKeyboardToolbar;
}
Note, un clavier matériel peut être présent mais non utilisé.
j'utilise une variation sur la réponse de Sarah Elan. J'ai eu des problèmes avec son approche dans certains points de vue. Je n'ai jamais vraiment compris ce qui a causé le problème. Mais voici une autre façon de déterminer si c'est un clavier externe iOS9 'undo' bar que vous avez, plutôt que le clavier complet.
il n'est probablement pas très vers l'avant compatible car s'ils changent la taille de la barre d'Annulation, ce freins. Mais, il fait le travail. Je me félicite des critiques formulées à ce sujet. doit y avoir une meilleure façon...
//... somewhere ...
#define HARDWARE_KEYBOARD_SIZE_IOS9 55
//
+ (BOOL) isExternalKeyboard:(NSNotification*)keyboardNotification {
NSDictionary* info = [keyboardNotification userInfo];
CGRect keyboardEndFrame;
[[info valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
CGRect keyboardBeginFrame;
[[info valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBeginFrame];
CGFloat diff = keyboardEndFrame.origin.y - keyboardBeginFrame.origin.y;
return fabs(diff) == HARDWARE_KEYBOARD_SIZE_IOS9;
}
solution API privée: (doivent saisir le fichier d'en - tête privé-utiliser RuntimeViewer).
fonctionne bien pour les applications d'entreprise, où vous n'avez pas de restrictions AppStore.
#import "UIKit/UIKeyboardImpl.h"
+ (BOOL)isHardwareKeyboardMode
{
UIKeyboardImpl *kbi = [UIKeyboardImpl sharedInstance];
BOOL externalKeyboard = kbi.inHardwareKeyboardMode;
NSLog(@"Using external keyboard? %@", externalKeyboard?@"YES":@"NO");
return externalKeyboard;
}
vous pouvez vous abonner à la notification lorsque le périphérique externe est connecté:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceConnected:) name:EAAccessoryDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceDisconnected:) name:EAAccessoryDidDisconnectNotification object:nil];
[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];
ou juste récupérer la liste des dispositifs attachés:
EAAccessoryManager* accessoryManager = [EAAccessoryManager sharedAccessoryManager];
if (accessoryManager)
{
NSArray* connectedAccessories = [accessoryManager connectedAccessories];
NSLog(@"ConnectedAccessories = %@", connectedAccessories);
}
vous pouvez essayer de vérifier les périphériques qui sont des services de publicité en utilisant noyau Bluetooth
CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[centralManager scanForPeripheralsWithServices:nil options:nil];
et vous devez mettre en œuvre le délégué:
- (void)centralManager:(CBCentralManager * _Nonnull)central
didDiscoverPeripheral:(CBPeripheral * _Nonnull)peripheral
advertisementData:(NSDictionary<NSString *,
id> * _Nonnull)advertisementData
RSSI:(NSNumber * _Nonnull)RSSI{
}