iOS 8 Création d'un clavier personnalisé dans Swift

À partir de iOS 8, vos applications peuvent étendre des fonctionnalités et du contenu personnalisés au-delà de votre application et les rendre accessibles aux utilisateurs lorsqu'ils utilisent d'autres applications ou le système d'exploitation. Un moyen d'étendre le système d'exploitation consiste à créer un clavier personnalisé..

Dans ce tutoriel, je vais vous montrer comment créer votre propre clavier personnalisé à l'aide de Swift et des nouvelles API d'extension d'application. Avant de faire cela, nous allons voir ce qu’une extension de clavier peut faire, ce qu’elle ne peut pas faire et ce qu’elle devrait faire pour être approuvée pour l’App Store..

1. Vue d'ensemble

Un clavier personnalisé remplace le clavier système pour les utilisateurs qui souhaitent des fonctionnalités, telles qu'une nouvelle méthode de saisie de texte ou la possibilité de saisir du texte dans une langue non prise en charge par le système d'exploitation..

La fonction essentielle d’un clavier personnalisé est simple: répondre à des tapotements, des gestes ou d’autres événements de saisie et fournir du texte sous la forme d’un clavier non attribué. NSString objet au point d'insertion de texte de l'objet de saisie actuel.

Lorsqu'un utilisateur choisit un clavier, il reste celui par défaut à chaque fois qu'il ouvre une application. Pour cette raison, le clavier doit permettre à l'utilisateur de passer à un autre clavier.

Il existe deux éléments de développement essentiels pour chaque clavier personnalisé:
Confiance. Votre clavier personnalisé vous donne accès à ce que l'utilisateur tape. La confiance entre vous et votre utilisateur est donc essentielle..
Une touche «clavier suivant». L'abondance qui permet à un utilisateur de changer de clavier fait partie de l'interface utilisateur du clavier. vous devez en fournir un sur votre clavier. - Guide de programmation des extensions d'applications

Si vous n’avez besoin que d’ajouter quelques boutons au clavier du système, vous devez examiner les vues personnalisées pour la saisie des données..

2. Conditions requises et limitations

Ce qu'un clavier personnalisé ne peut pas faire

Votre clavier personnalisé ne peut pas entrer dans certains objets de saisie de texte. Celles-ci incluent des champs de texte sécurisés pour la saisie de mots de passe et d’objets du clavier téléphonique, tels que les champs de numéro de téléphone dans l’écran. Contacts application.

Votre clavier personnalisé n'a pas accès à la hiérarchie de vues de l'entrée, il ne peut pas contrôler le curseur et ne peut pas sélectionner de texte. De plus, le clavier personnalisé ne peut rien afficher au-dessus de la rangée supérieure. Le clavier système n'est pas limité par ces contraintes. Par exemple, une extension s'affiche lorsque vous appuyez sur une touche pour indiquer à l'utilisateur quelle touche a été utilisée..

La ligne rouge indique la limite supérieure d'un clavier personnalisé.

Bac à sable

Par défaut, un clavier n'a pas d'accès au réseau et ne peut pas partager de fichiers avec l'application qui le contient. Pour activer ces fonctionnalités, définissez la valeur du paramètre RequestsOpenAccess clé dans le Info.plist déposer dans OUI. Cela élargit le bac à sable du clavier, comme décrit dans le Guide de programmation d'Apple App Extension..

Si vous demandez un accès ouvert, votre clavier acquiert les fonctionnalités suivantes, chacune ayant une responsabilité concomitante:

  • accès aux services de localisation et à la base de données du carnet d'adresses, chacun nécessitant l'autorisation de l'utilisateur lors du premier accès
  • possibilité d'utiliser un conteneur partagé avec l'application contenant le clavier, ce qui active des fonctionnalités, telles que la fourniture d'une interface utilisateur de gestion de lexique personnalisée dans l'application contenant
  • possibilité d'envoyer des frappes au clavier et d'autres événements d'entrée pour un traitement côté serveur
  • accès à iCloud, que vous pouvez utiliser, par exemple, pour vous assurer que les paramètres du clavier et votre lexique de correction automatique personnalisé sont à jour sur tous les appareils appartenant à l'utilisateur
  • accès à Game Center et achat via l'application via l'application correspondante
  • possibilité de travailler avec des applications gérées si votre clavier est conçu pour prendre en charge la gestion des appareils mobiles (MDM)

Assurez-vous de lire le document «Designing for User Trust» d'Apple, qui décrit vos responsabilités en matière de respect et de protection des données utilisateur dans le cas où vous demandez un accès ouvert..

3. Comment ça marche

Dans sa forme la plus élémentaire, nous avons une application qui contient une extension de clavier et un UIInputViewController qui contrôle le clavier et répond aux événements de l'utilisateur.

le Clavier personnalisé le modèle contient une sous-classe de UIInputViewController, qui est le contrôleur de vue principal de votre clavier. Regardons l'interface pour avoir une idée de son fonctionnement.

classe UIInputViewController: UIViewController, UITextInputDelegate, NSObjectProtocol var inputView: UIInputView! var textDocumentProxy: NSObject! get func rejetKeyboard () func advanceToNextInputMode () // Ceci ne fournira pas de référentiel complet du vocabulaire d'une langue. // Il est uniquement destiné à compléter les lexiques existants. func requestSupplementaryLexiconWithCompletion (completionHandler: ((UILexicon!) -> Void)!) 
  • inputView est la vue utilisée pour le clavier, elle est identique à la vue propriété
  • licencier Clavier méthode peut être appelée pour ignorer le clavier
  • advanceToNextInputMode est utilisé pour changer de clavier
  • textDocumentProxy est l'objet que vous utiliserez pour interagir avec la saisie de texte actuelle
self.textDocumentProxy.insertText ("Tuts +") // insère la chaîne "Tuts +" au point d'insertion self.textDocumentProxy.deleteBackward () // supprime le caractère situé à gauche du point d'insertion. 
  • UIInputViewController conforme à la UITextInputDelegate protocole, vous avertissant lorsque le texte ou la sélection de texte change via le selectionWillChangeselectionDidChangetextWillChange et textDidChangeévénements

4. Faire un clavier de calcul

Créons un clavier personnalisé pour rendre tout cela un peu plus tangible. Nous allons créer un clavier simple capable de gérer la saisie numérique et des opérations simples. Nous allons utiliser un fichier XIB pour l'interface utilisateur du clavier.

Étape 1: Créer un nouveau projet

Ouvrez Xcode 6, créez un nouveau Application à vue unique et sélectionnez Rapide comme langage de programmation. Nomme le CalculatriceClavier.

Étape 2: Ajouter un champ de texte

Ouvrir Tableau principal et faites glisser un champ de texte du Bibliothèque d'objets. Nous allons l'utiliser pour tester le clavier plus tard. Centrez le champ de texte et ajoutez les contraintes de mise en page nécessaires, comme indiqué ci-dessous..

Si vous appelez textField.becomeFirstResponder () dans viewDidLoad le clavier s'ouvrira lorsque vous démarrez l'application.

Étape 3: Ajouter l'extension de clavier

Sélectionnez le fichier de projet dans le Navigateur de projet et ajoutez une nouvelle cible en cliquant sur le bouton plus en bas.

Sélectionner Extension de l'application à gauche, choisissez la Clavier personnalisé modèle et nommez-le Calculatrice.

Cela va créer un nouveau groupe nommé Calculatrice, contenant deux fichiers KeyboardViewController.swift et Info.plist.

Étape 4: nettoyage

Ouvrir KeyboardViewController.swift. Le modèle de clavier comporte un bouton, permettant à l’utilisateur de basculer d’un clavier à l’autre. Supprimer le code dans le viewDidLoad méthode.

Étape 5: Création de l'interface utilisateur

Clic droit le Calculatrice groupe et sélectionnez Nouveau fichier… . Sélectionnez le Interface utilisateur section à gauche, choisissez la Vue modèle et nommez-le Calculatrice. Cela devrait créer un fichier nommé Calculator.xib.

Ouvrez le fichier XIB et, dans le répertoire Inspecteur d'attributs à droite, définissez la taille sur Forme libre et la barre d'état pour Aucun.

dans le Inspecteur de taille définir la largeur de la vue sur 320 et la hauteur à 160.

Faites glisser un bouton du Bibliothèque d'objets à la vue. dans le Inspecteur d'attributs, mettre le titre à 1. dans le Inspecteur de taille, régler la largeur et la hauteur du bouton sur 30. Déplacez le bouton dans le coin supérieur droit de la vue jusqu'à ce qu'il s'aligne avec les marges..

Copiez le bouton en cliquant dessus et en le faisant glisser tout en appuyant sur la Option clé. Placez le deuxième bouton en dessous du premier.

Sélectionnez les boutons en appuyant sur Command-A et copiez les boutons. Positionnez les nouveaux boutons sous les premier et deuxième boutons.

Répétez le processus pour créer une autre colonne de boutons jusqu'à obtenir quatre colonnes de boutons..


Ensuite, sélectionnez la colonne de gauche et faites une copie alignée avec le bord gauche de la vue..

Définissez la largeur des boutons sur 140 points. Remplacez le bouton en haut à gauche par une étiquette de même taille que le bouton. Renommez les boutons comme dans la capture d'écran ci-dessous.

Attribuez à la vue une couleur d'arrière-plan bleuâtre et définissez la couleur d'arrière-plan des boutons sur blanc avec une opacité de 15%. Et pour l'étiquette d'affichage, faites-le noir avec une opacité de 15%. Définissez la taille du texte sur 18 points pour chaque objet d'interface utilisateur et définissez la couleur du texte sur blanc. L'interface utilisateur devrait maintenant ressembler à ceci:

Étape 6: Chargement de l'interface utilisateur

Nous devons d’abord créer une propriété dans laquelle stocker l’interface utilisateur..

Classe KeyboardViewController: UIInputViewController var calculatorView: UIView!… 

Créez une méthode nommée loadInterface et appelez-le dans le viewDidLoad méthode du KeyboardViewController.

classe KeyboardViewController: UIInputViewController … remplacer func viewDidLoad () super.viewDidLoad () loadInterface () func loadInterface () // charger le fichier nib var calculatorNib = UINib (nibName: "Calculator", bundle: nil) // instantiate la vue calculatorView = calculatorNib.instantiateWithOwner (self, options: nil) [0] en tant que UIView // ajoute l'interface à la vue principale view.addSubview (calculatorView) // copie la couleur d'arrière-plan view.backgroundColor = calculatorView.backgroundColor… 

Étape 7: Test du clavier

À ce stade, vous devriez pouvoir tester votre nouveau clavier. Avec le CalculatriceClavier schéma sélectionné, créez et exécutez l’application sur votre appareil. Cela va ajouter un nouveau clavier à votre appareil. Cependant, avant de pouvoir l'utiliser, vous devez d'abord l'installer..

Aller à Réglages > Général > Clavier > Claviers et sélectionnez Ajouter un nouveau clavier. Là vous trouverez le Calculatrice clavier dans la liste des claviers tiers. Sélectionnez et installez le clavier. La prochaine fois que vous ouvrirez le clavier, vous devriez pouvoir voir votre nouveau clavier en appuyant sur le bouton du clavier suivant..

Si vous utilisez iOS Simulator, le clavier personnalisé risque de ne pas fonctionner dans votre application. Pour voir le clavier, appuyez sur home et ouvrez Spotlight..

Étape 8: Clavier suivant

Créez une propriété pour le prochain bouton du clavier dans KeyboardViewController classe.

classe KeyboardViewController: UIInputViewController @IBOutlet var nextKeyboardButton: UIButton!… 

Ouvrir Calculator.xib , Sélectionner Propriétaire du fichier, et dans le Inspecteur d'identité changer sa classe à KeyboardViewController.

Clic droit sur le Clavier suivant bouton et connectez une prise de référencement au Propriétaire du fichier.

dans le loadInterface méthode, nous ajoutons une action à la nextKeyboard bouton comme indiqué ci-dessous.

class KeyboardViewController: UIInputViewController … func loadInterface () … // Cela fera que le bouton appellera advanceToNextInputMode () lorsque tapé sur nextKeyboardButton.addTarget (self, action: "advanceToNextInputMode", pourControlEvents).

Étape 9: Affichage du numéro

Créez une propriété pour l'affichage et connectez la prise de référence dans Interface Builder..

classe KeyboardViewController: UIInputViewController @IBOutlet var display: UILabel!…

Créez une méthode nommée clearDisplay et appelez-le dans le viewDidLoad méthode, après avoir appelé loadInterface. L'affichage devrait maintenant montrer 0 quand vous ouvrez le clavier.

classe KeyboardViewController: UIInputViewController … remplacer func viewDidLoad () super.viewDidLoad () loadInterface () clearDisplay ()… @IBAction func clearDisplay () display.text = "0"

Connectez le C boutons retoucher l'intérieur événement au clearDisplay méthode dans Interface Builder.

Étape 10: Entrée du nombre

Temps nécessaire pour gérer la saisie numérique. Lorsque vous ouvrez le clavier, cela indique 0 sur l'écran. Si vous appuyez sur une touche numérique, il convient de remplacer l'affichage par ce numéro. Créer une propriété nommée shouldClearDisplayBeforeInserting mettre en œuvre ce comportement.

Créez une méthode nommée didTapNumber et connectez-le dans Interface Builder à tous les boutons numériques du retoucher l'intérieur un événement. La méthode utilise le titleLabel du bouton pour déterminer quel numéro a été exploité.

class KeyboardViewController: UIInputViewController var devrait (=) si var oldDisplay = affiche? .text! display.text = "\ (oldDisplay) \ (numberAsNSString.intValue)" display.text = "\ (numberAsNSString.intValue)" 

Mettre à jour le clearDisplay méthode comme indiqué ci-dessous.

classe KeyboardViewController: UIInputViewController … @IBAction func clearDisplay () display.text = "0" shouldClearDisplayBeforeInserting = true

Le code du clavier est dans une cible différente de celle de votre application. Pour cette raison, les journaux de débogage ne sont pas visibles. Pour voir les journaux du Calculatrice cible, ouvrez le journal système à partir du simulateur iOS.

Étape 11: Entrée de points

Le bouton pour insérer un point devrait ajouter un point à l’affichage, mais seulement s’il n’y en avait pas encore..

classe KeyboardViewController: UIInputViewController … @IBAction func didTapDot () si laissez input = display? .text var hasDot = false pour ch dans input.unicodeScalars if ch == "." hasDot = true break si hasDot == false display.text = "\ (entrée)."  

Étape 12: Insérer du texte

Le bouton pour insérer du texte doit ajouter le texte d'affichage de la calculatrice au point d'insertion. Pour ce faire, nous utilisons le textDocumentProxy propriété comme indiqué ci-dessous.

classe KeyboardViewController: UIInputViewController … @IBAction func didTapInsert () var proxy = textDocumentProxy comme UITextDocumentProxy si let input = s'affiche? .text comme String? proxy.insertText (input)

Étape 13: Opérations de manutention

Parce que nous implémentons un clavier simple qui ne supporte pas les arbres d'expression, 1 + 2 * 3 sera égal 9. Nous allons utiliser un modèle plus simple dans lequel la calculatrice a un emplacement de mémoire interne sur lequel elle peut appliquer des opérations..

Prenons une entrée simple pour comprendre le fonctionnement de l'algorithme de la calculatrice:

  • robinets de l'utilisateur 1, l'affichage devrait changer de 0 à 1
  • robinets de l'utilisateur +, la calculatrice ne doit pas oublier d’ajouter le prochain nombre saisi à 1
  • robinets de l'utilisateur 2, l'affichage devrait changer de 1 à 2
  • robinets de l'utilisateur *, l’affichage et la mémoire interne de la calculatrice devraient changer à 3, la calculatrice doit penser à multiplier la mémoire interne par le prochain nombre saisi
  • robinets de l'utilisateur 3, l'affichage doit rester 3
  • robinets de l'utilisateur =, la calculatrice doit appliquer la dernière opération et l'affichage doit passer à 9

Observations:

  • la calculatrice doit se rappeler de la prochaine opération à appliquer
  • après avoir entré un nombre si une opération ou un équivalent est appuyé, la calculatrice doit appliquer la dernière opération mémorisée
  • si l'utilisateur appuie sur deux opérations ou plus sans saisir de chiffre, la calculatrice doit se rappeler de la dernière
  • après l'application d'une opération, l'affichage doit être mis à jour avec le résultat
  • après l'affichage d'un résultat, l'écran doit s'effacer avant d'écrire un autre numéro

Pour mettre en œuvre la calculatrice, nous allons avoir besoin de:

  • un mémoire interne propriété qui stocke le résultat temporaire
  • une propriété qui stocke le nextOperation
  • un autre qui à retenir si elle doit appliquer la nextOperation après avoir appuyé sur une opération
enum Operation cas Addition Cas cas de multiplication Cas soustraction Cas de division Aucun classe KeyboardViewController: UIInputViewController var internalMemory = 0.0 var nextOperation = Operation.None var shouldCompute = false… 

Créez une méthode nommée didTapOperation et connectez-le aux boutons d'opération retoucher l'intérieur événement dans Interface Builder. La méthode utilisera le titre du bouton pour déterminer quelle opération a été activée.

classe KeyboardViewController: UIInputViewController … @IBAction func didTapOperation (opération: UIButton) if ifCompute computeLastOperation () si var op = operation.titleLabel? .text commutateur op cas "+": nextOperation = Operation.Addition case "- ": nextOperation = Opération.Subtraction soustraction" X ": nextOperation = Opération.Offre de multiplication"% ": nextOperation = Operation.Division par défaut: nextOperation = Operation.None

Créer et mettre en œuvre le computeLastOperation méthode.

class KeyboardViewController: UIInputViewController … @IBAction func computeLastOperation () // rappelez-vous de ne pas calculer si une autre opération est actionnée sans saisir un autre numéro. shouldCompute = false si var input = display? .text var inputAsDouble = (entré comme NSString). doubleValue var result = 0.0 // applique l'opération switch nextOperation case .Addition: result = internalMemory + inputAsDouble case .Subtraction: result = internalMemory - inputAsDouble case .Multiplication: result = internalMemory * inputAsDouble case .Division: result = internalMemory / inputAsDouble default : result = 0.0 nextOperation = Operation.None var output = "\ (result)" // si le résultat est un entier, ne pas afficher le point décimal si output.hasSuffix (". 0") output = "\ ( Int (result)) " // truncatingg aux cinq derniers chiffres var components = output.componentsSeparatedByString (". ") Si components.count> = 2 var beforePoint = components [0] var afterPoint = components [1] si afterPoint. longueurOctets UsingEncoding (NSUTF8StringEncoding)> 5 let index: String.Index = advance (afterPoint.startIndex, 5) afterPoint = afterPoint.substringToIndex (index) output = beforePoint + "." + afterPoint // met à jour l'affichage display.text = output // enregistre le résultat internalMemory = result // n'oubliez pas d'effacer l'affichage avant d'insérer un nouveau numéro shouldClearDisplayBeforeInserting = true

Mettre à jour le clearDisplayMethod comme indiqué ci-dessous. Lorsque l'utilisateur commence à écrire le premier numéro, la mémoire interne doit être réglée sur 0 et nextOperation devrait être addition. De cette façon, après que l'utilisateur ait entré le premier numéro et appuyé sur une opération, la calculatrice mémorisera le numéro entré..

classe KeyboardViewController: UIInputViewController … @IBAction func clearDisplay () display.text = "0" internalMemory = 0 nextOperation = Operation.Addition shouldClearDisplayBeforeInserting = true

Étape 14: Touches finales

Utilisons le IBInspectable attribut de déclaration pour ajouter un rayon de coin aux boutons et à l’affichage. Tout d’abord, créez une sous-classe de UIButton et UILabel.

classe RoundButton: UIButton @IBInspectable var cornerRadius: CGFloat = 0 didSet layer.cornerRadius = cornerRadius classe RoundLabel: UILabel @IBInspectable var cornerRadius: CGFloat = 0 didSet layer.cornerRadius 

Dans Interface Builder, sélectionnez les boutons et remplacez leur classe par Bouton rond dans le Inspecteur d'identité. dans le Inspecteur d'attributs, vous devriez voir le nouvel attribut rayon de coin.

Faites la même chose pour l'étiquette d'affichage. Votre clavier devrait maintenant ressembler à ceci.

Conclusion

Vous devriez maintenant pouvoir créer un clavier personnalisé dans iOS à l'aide des API d'extension d'application. N'oubliez pas que chaque clavier personnalisé doit disposer d'un moyen de passer au clavier suivant et que votre clavier ne peut pas se connecter à Internet, accéder aux services de localisation ou parler avec son application par défaut, mais vous pouvez demander ces fonctionnalités..

Le système utilisera le clavier par défaut pour les champs sécurisés, tels que les champs de mot de passe et de numéro de téléphone. N'oubliez pas que le code du clavier personnalisé réside dans une cible distincte. Pour cette raison, les journaux de débogage ne sont pas visibles. Pour les voir, ouvrez le journal système à partir du simulateur iOS..