3DTouch - Escalas no iPhone: Introdução

Depois que o iPhone 6s e o iPhone 6s Plus entraram no mercado com telas compatíveis com a tecnologia 3D Touch , um aplicativo para pesar ameixas e pêssegos apareceu quase imediatamente na App Store.

imagem

Não sei dizer com certeza por que exatamente essas frutas, mas definitivamente posso dizer por que exatamente essas frutas. O fato é que o sensor de tela do iPhone trabalha com o princípio de detectar vazamentos de corrente da superfície do sensor e, para esse vazamento, você precisa de um dedo ativo ou de algo com capacidade elétrica. Acho que todo mundo sabe que as telas dos dispositivos i não funcionam com uma caneta ou prego de plástico. Por isso, era impossível pesar algo metálico nessa aplicação. Mas as frutas têm capacidade elétrica, o sensor é acionado e o 3D Touch funciona diretamente normalmente.

Muito rapidamente, este aplicativo foi removido da App Store. Pessoalmente, parece-me que isso foi feito devido aos usuários de mente estreita que tentaram pesar libras em seus dispositivos. Obviamente, os dispositivos quebraram e os levaram aos centros de serviço. E eles disseram algo da série: "O aplicativo foi baixado da loja oficial e eles não avisaram que era impossível ...".

Como resultado, não existem aplicativos na loja, mas ninguém nos impedirá de criá-lo para nós mesmos.

Desafio


Precisamos escrever um aplicativo, que consiste em um controlador, no qual haverá uma inscrição convidativa, um círculo desenhado no centro da tela, indicadores de peso em gramas e porcentagem da força determinada (mais adiante, no texto, ficará mais claro). Quando você clica na tela, um círculo aparece no ponto de toque, o que aumenta ou diminui dependendo da pressão. É preciso dizer imediatamente que em um simulador essa aplicação não pode ser testada. Portanto, você precisará executar o aplicativo em um dispositivo real. No final, você deve obter esse aplicativo:

imagem

Criação de projeto


Abra o Xcode, escolha criar um novo projeto, modelo de aplicativo de exibição única

imagem

Construindo uma interface no Xcode


Vá para o Storyboard , arraste vários UILabels da biblioteca de elementos para o controlador, coloque-os mais perto das bordas superior ou inferior do controlador. Aconteceu assim:

imagem

Para apelo estético, destacaremos o local em que colocaremos objetos em um círculo vermelho. Você pode tirar uma foto pronta com um círculo, mas este não é o nosso método)). Vamos desenhar os círculos usando os métodos do Core Graphics . Será mais conveniente criar uma classe herdada do UIView e já trabalhar com ela.

Adicione um novo arquivo ao projeto, denomine ScaleView . Crie uma classe ScaleView neste arquivo que herda do UIView .

imagem

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

Em seguida, vá para o StoryBoard , transfira-o para o controlador da biblioteca de elementos do UIView e coloque-o no centro do nosso controlador. Selecione o UIView recentemente adicionado e, no Identity Inspector, defina a classe ScaleView que criamos anteriormente.

imagem

Além disso, com a ajuda de constantes, você pode definir as regras para o posicionamento relativo dos elementos na tela. Parece assim para mim:

imagem

Desenhe círculos


Vá para o arquivo ScaleView.swift . Na classe ScaleView, criamos o método draw (_ rect :) , que usaremos para desenhar dentro da área de exibição deste UIView .

Adicione o seguinte código ao método 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. Temos o contexto gráfico no qual desenharemos
  2. Definimos a cor com a qual desenharemos. Nesse caso. É vermelho
  3. Defina a largura da linha com a qual desenharemos.
  4. Definimos o caminho para desenhar na forma de um arco, cujo centro está localizado no centro do ScaleView, com um raio igual à metade da largura do ScaleView menos 14 (isto é para encaixar o arco na vista visível) e um arco longo - 360 graus em toda a circunferência. Observe que meus dígitos de largura são codificados no parágrafo anterior usando constantes.
  5. Nós desenhamos no caminho dado com os parâmetros dados

Você pode compilá-lo para verificação, mas também pode definir uma diretiva para exibir alterações diretamente no Interface Builder .

Toda a mágica da diretiva @IBDesignable . Marque a classe ScaleView com esta diretiva .

 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() } } 

Depois disso, vá para o StoryBoard , espere um pouco e você verá um círculo vermelho pintado no centro do ViewController

imagem

Vamos praticar e desenhar outro círculo menor e mais fino. Para fazer isso, adicione o seguinte código ao método draw (_ rect :) no arquivo 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() 

Eu acho que está claro, e então adicionamos. De fato, adicionamos mais um círculo, cinza, raios um quarto da largura do ScaleView e uma largura de um ponto.

Resultados no StoryBoard :

imagem

A parte final do nosso trabalho preparatório será a criação de pontos de venda para o ScaleView e dois UILabels , que mostrarão a força de pressionar a tela em porcentagem e o peso em gramas. Se arrastar com a tecla Ctrl os itens do ViewController , criarão as saídas necessárias.

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

Diretamente - escalas


Então, chegamos perto do momento de medir a força de pressionar a tela. Vá para ViewController e, no método viewDidLoad () , adicione valores iniciais para todos os UILabel

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

Como todos os processos associados aos toques na tela, eles podem ser capturados no controlador no método touchesMoved (_: :) . Este método funciona quando a tela toca a tempo. I.e. Se o dedo estiver na tela ou em movimento, esse método funcionará e você poderá rastrear todos os toques e suas propriedades. Adicione-o ao ViewController e escreva o seguinte código:

 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) " } } } } } 

Toda a mecânica do aplicativo Libra iOS é esse método. Tudo o resto que faremos mais nesta lição são melhorias. Já fizemos todo o trabalho básico. Vamos desmontar

  1. De todo o conjunto de toques da tela, escolhemos o primeiro
  2. Esta diretiva verifica o sistema operacional instalado no dispositivo e pula ainda mais se a versão do sistema operacional for 9.0 ou superior. O trabalho com o 3D Touch só foi possível com a 9ª versão do iOS. Tentar lidar com isso na dor de versões anteriores não faz sentido
  3. E nesta linha, o dispositivo está sendo testado para suporte à tela com a função 3D Touch . Afinal, a versão 10 do iOS também pode ficar no iPhone 6, mas com isso a tela deste smartphone não começará a distinguir a força da pressão. Essa inspeção deve ser feita sob os rigorosos requisitos da Apple.
  4. Um toque possui uma propriedade de força na qual a força é transmitida sempre que o método touchesMoved (_: :) funciona. E nesta linha, comparamos o valor da força de pressão atual e o valor máximo possível da força de pressão. E se a força de prensagem for maior que a máxima, em nosso UILabel transferimos os valores máximos, ou seja, 100 % da força e 385 gramas. Note-se porque é 385 gramas. O fato é que a tecnologia 3D Touch é fabricada de tal maneira que 100% da força de prensagem corresponde a 385 gramas. Assim, obter uma porcentagem da força de pressão, podemos calcular facilmente o peso em gramas.
  5. Aqui fazemos esses cálculos. Nesta linha, calculamos a porcentagem de pressão
  6. Aqui calculamos o peso em gramas, com base na fórmula 100% = 385 gramas
  7. Este é um arredondamento simples de gramas para o conjunto
  8. Passamos a porcentagem de força e peso em gramas para o nosso UILabel

Antes de iniciar e verificar o aplicativo, você precisa adicionar outro método que funcione quando todos os toques na tela param em Ended (: :) , para definir a posição inicial dos nossos UILabels e passar neles os valores 0% e 0 gramas. Adicione este método à classe ViewController .

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

Agora você pode compilar o aplicativo e verificar. Obviamente, você precisa fazer isso em um dispositivo real para ver o resultado. O simulador não é capaz de emular cliques forçados na tela.

imagem

Melhorias


A funcionalidade principal está pronta, mas quando escrevi este aplicativo, decidi adicionar três coisas:

  1. Ao atingir o valor máximo, quero que a resposta da vibração funcione
  2. A atualização dos valores no UILabel acontece muito rapidamente (acho que você notou isso ao testar), portanto, é necessário adicionar alguma suavidade.
  3. Um círculo semitransparente deve aparecer no momento do pressionamento. Seu diâmetro deve aumentar com o aumento da pressão e diminuir com a diminuição da pressão

Trataremos dessas adições no seguinte artigo :-)

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


All Articles