3DTouch - Échelles sur iPhone: mise en route

Après que l'iPhone 6s et l'iPhone 6s Plus soient entrés sur le marché avec des écrans prenant en charge la technologie 3D Touch , une application pour peser les prunes et les pêches est apparue presque immédiatement dans l'App Store.

image

Je ne peux pas dire avec certitude pourquoi exactement ces fruits, mais je peux certainement dire pourquoi précisément les fruits. Le fait est que le capteur d'écran de l'iPhone fonctionne sur le principe de détecter les fuites de courant de la surface du capteur, et pour cette fuite, vous avez besoin d'un doigt vivant ou de quelque chose qui a une capacité électrique. Je pense que tout le monde sait que les écrans des appareils i ne fonctionnent pas sur un stylet ou un ongle en plastique. C'est pourquoi il était impossible de peser quelque chose de métallique sur cette application. Mais les fruits ont une capacité électrique, le capteur est déclenché sur eux et le 3D Touch fonctionne directement normalement.

Très rapidement, cette application a été supprimée de l'App Store. Personnellement, il me semble que cela a été fait en raison des utilisateurs étroits d'esprit qui ont essayé de peser des kilos sur leurs appareils. Bien sûr, les appareils sont tombés en panne et ils les ont transportés dans des centres de service. Et là, ils ont dit quelque chose de la série: "L'application a été téléchargée depuis la boutique officielle, et ils n'y ont pas averti que c'était impossible ...".

En conséquence, il n'y a pas de telles applications dans le magasin, mais personne ne nous empêchera de le créer pour nous-mêmes.

Défi


Nous devons écrire une application, qui se compose d'un contrôleur, sur lequel il y aura une inscription invitante, un cercle dessiné au centre de l'écran, des indicateurs de poids en grammes et en pourcentage de la force déterminée (plus loin dans le texte, ce sera plus clair). Lorsque vous cliquez sur l'écran, un cercle apparaît au point de contact, qui augmente ou diminue en fonction de la pression. Il faut dire tout de suite que sur un simulateur une telle application ne peut pas être testée. Par conséquent, vous devrez exécuter l'application sur un appareil réel. À la fin, vous devriez obtenir une telle application:

image

Création de projet


Ouvrez Xcode, choisissez créer un nouveau projet, modèle d' application à vue unique

image

Construire une interface dans Xcode


Accédez au Storyboard , faites glisser plusieurs UILabels de la bibliothèque d'éléments sur le contrôleur, placez-les plus près des bords supérieurs ou inférieurs du contrôleur. Il s'est avéré comme ceci:

image

Pour un attrait esthétique, nous mettrons en évidence l'endroit où nous placerons les objets dans un cercle rouge. Vous pouvez prendre une photo prête à l'emploi avec un cercle, mais ce n'est pas notre méthode)). Nous allons dessiner les cercles en utilisant les méthodes de Core Graphics . Il sera plus pratique de créer une classe héritière à partir d'UIView et de travailler déjà avec elle.

Ajoutez un nouveau fichier au projet, nommez-le ScaleView . Créez une classe ScaleView dans ce fichier qui hérite d' UIView .

image

import UIKit class ScaleView: UIView { override func draw(_ rect: CGRect) { } } 

Ensuite, accédez au StoryBoard , transférez-le sur le contrôleur à partir de la bibliothèque d'éléments UIView et placez-le au centre de notre contrôleur. Sélectionnez la nouvelle UIView ajoutée et dans l' inspecteur d'identité, définissez la classe ScaleView que nous avons créée précédemment.

image

De plus, à l'aide de constantes, vous pouvez définir les règles de positionnement relatif des éléments à l'écran. Cela ressemble à ceci pour moi:

image

Dessinez des cercles


Accédez au fichier ScaleView.swift . Dans la classe ScaleView, nous avons créé la méthode draw (_ rect :) , que nous utiliserons pour dessiner à l'intérieur de la zone d'affichage de cette UIView .

Ajoutez le code suivant à la méthode draw (_ rect :)

 override func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext() // 1 context?.setStrokeColor(UIColor.red.cgColor) // 2 context?.setLineWidth(14.0) // 3 context?.addArc(center: CGPoint(x: 375 / 2, y: 375 / 2), radius: 375 / 2 - 14, startAngle: 0, endAngle: 2 * CGFloat(M_PI), clockwise: true) // 4 context?.strokePath() // 5 } 

  1. On obtient le contexte graphique dans lequel on va dessiner
  2. Nous définissons la couleur avec laquelle nous allons dessiner. Dans ce cas. Est rouge
  3. Définissez la largeur de la ligne avec laquelle nous allons dessiner.
  4. Nous définissons le chemin pour dessiner sous la forme d'un arc, dont le centre est situé au centre de la ScaleView, avec un rayon égal à la moitié de la largeur de la ScaleView moins 14 (c'est pour adapter l'arc dans la vue visible), et un arc long - 360 degrés sur toute la circonférence. Veuillez noter que mes chiffres de largeur sont codés en dur dans le paragraphe précédent à l'aide de constantes.
  5. Nous dessinons sur le chemin donné avec les paramètres donnés

Vous pouvez le compiler pour vérification, mais vous pouvez également définir une directive pour afficher les modifications directement dans Interface Builder .

Toute la magie de la directive @IBDesignable . Marquez la classe ScaleView avec cette directive .

 import UIKit @IBDesignable class ScaleView: UIView { override func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext() context?.setStrokeColor(UIColor.red.cgColor) context?.setLineWidth(14.0) context?.addArc(center: CGPoint(x: 375 / 2, y: 375 / 2), radius: 375 / 2 - 14, startAngle: 0, endAngle: 2 * CGFloat(M_PI), clockwise: true) context?.strokePath() } } 

Après cela, allez au StoryBoard , attendez un peu et vous verrez un cercle rouge peint au centre du ViewController

image

Pratiquons et dessinons un autre cercle plus petit et plus fin. Pour ce faire, ajoutez le code suivant à la méthode draw (_ rect :) dans le fichier ScaleView :

 context?.setLineWidth(1.0) context?.setStrokeColor(UIColor.lightGray.cgColor) context?.addArc(center: CGPoint(x: 375 / 2, y: 375 / 2), radius: 375 / 4 - 14, startAngle: 0, endAngle: 2 * CGFloat(M_PI), clockwise: true) context?.strokePath() 

Je pense que c'est clair, alors nous avons ajouté. En fait, nous avons ajouté un cercle de plus, gris, des rayons d'un quart de la largeur du ScaleView et une largeur d'un point.

Résultats dans StoryBoard :

image

La dernière partie de notre travail préparatoire sera la création de prises pour ScaleView et deux étiquettes UIL , qui montreront la force d'appuyer sur l'écran en pourcentage et le poids en grammes. Ctrl- glisser des éléments depuis le ViewController créera les prises nécessaires.

 @IBOutlet weak var scaleView: ScaleView! @IBOutlet weak var forceLabel: UILabel! @IBOutlet weak var grammLabel: UILabel! 

Directement - échelles


Ainsi, nous nous approchions du moment de mesurer la force de pression sur l'écran. Accédez à ViewController et dans la méthode viewDidLoad () ajoutez des valeurs de départ pour tous UILabel

 override func viewDidLoad() { super.viewDidLoad() forceLabel.text = "0% force" grammLabel.text = "0 " } 

Comme tous les processus associés aux tapotements d'écran, dans le contrôleur, ils peuvent être capturés par la méthode touchesMoved (_: :) . Cette méthode fonctionne lorsque l'écran touche à temps. C'est-à-dire Si le doigt est sur l'écran ou bouge dessus, cette méthode fonctionne et vous pouvez suivre toutes les touches et leurs propriétés. Ajoutez-le au ViewController et écrivez le code suivant:

 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { // 1 if #available(iOS 9.0, *) { // 2 if traitCollection.forceTouchCapability == UIForceTouchCapability.available { // 3 if touch.force >= touch.maximumPossibleForce { // 4 forceLabel.text = "100%+ force" grammLabel.text = "385 " } else { let force = (touch.force / touch.maximumPossibleForce) * 100 // 5 let grams = force * 385 / 100 // 6 let roundGrams = Int(grams) // 7 forceLabel.text = "\(Int(force))% force" // 8 grammLabel.text = "\(roundGrams) " } } } } } 

Toute la mécanique de l'application iOS Libra est cette méthode. Tout ce que nous ferons plus loin dans cette leçon est des améliorations. Nous avons déjà fait tout le travail de base. Prenons-le à part

  1. De l'ensemble des touches de l'écran, nous choisissons le premier
  2. Cette directive vérifie le système d'exploitation installé sur l'appareil et ne saute plus loin que si la version du système d'exploitation est 9.0 ou plus. Travailler avec 3D Touch n'est devenu possible qu'avec la 9e version d'iOS. Essayer de le gérer dans la douleur des versions antérieures n'a pas de sens
  3. Et dans cette ligne, l'appareil est testé pour la prise en charge de l'écran avec la fonction 3D Touch . Après tout, la version 10 d'iOS peut également se tenir sur l'iPhone 6, mais à partir de cela, l'écran de ce smartphone ne commencera pas à distinguer la force d'appuyer. Cette inspection doit être effectuée conformément aux exigences strictes d'Apple.
  4. Un toucher a une propriété de force dans laquelle la force est transmise à chaque fois que la méthode touchesMoved (_: :) fonctionne. Et dans cette ligne, nous comparons la valeur de la force de pression actuelle et la valeur maximale possible de la force de pression. Et si la force de pression est supérieure au maximum, alors dans notre UILabel nous transférons les valeurs maximales, à savoir 100 % de la force et 385 grammes. Il convient de noter pourquoi il est de 385 grammes. Le fait est que la technologie 3D Touch est conçue de telle manière que 100% de la force de pression correspond à 385 grammes. En conséquence, obtenez un pourcentage de la force de pressage, nous pouvons facilement calculer le poids en grammes.
  5. Ici, nous faisons ces calculs. Dans cette ligne, nous calculons le pourcentage de pression
  6. Ici, nous calculons le poids en grammes, sur la base de la formule 100% = 385 grammes
  7. Il s'agit d'un simple arrondi de grammes à l'ensemble
  8. Nous transmettons le pourcentage de force et de poids en grammes à notre UILabel

Avant de démarrer et de vérifier l'application, vous devez ajouter une autre méthode qui fonctionne lorsque toutes les touches de l'écran s'arrêtent toucheEnded (: :) , afin de définir la position initiale de nos étiquettes UIL et de leur transmettre les valeurs 0% et 0 grammes. Ajoutez cette méthode à la classe ViewController .

 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { forceLabel.text = "0% force" grammLabel.text = "0 " } 

Vous pouvez maintenant compiler l'application et vérifier. Bien sûr, vous devez le faire sur un véritable appareil pour voir le résultat. Le simulateur n'est pas en mesure d'émuler les clics forcés sur l'écran.

image

Améliorations


La fonctionnalité principale est prête, mais quand j'ai écrit cette application, j'ai décidé d'ajouter trois choses:

  1. Lorsque j'atteins la valeur maximale, je veux que la réponse aux vibrations fonctionne
  2. La mise à jour des valeurs dans UILabel se produit très rapidement (je pense que vous l'avez remarqué lors des tests), vous devez donc ajouter un peu de fluidité.
  3. Un cercle semi-transparent devrait apparaître au moment d'appuyer. Son diamètre devrait augmenter avec l'augmentation de la pression et diminuer avec la diminution de la pression

Nous traiterons de ces ajouts dans l' article suivant :-)

Source: https://habr.com/ru/post/fr417221/


All Articles