Compartilhar via


Introdução ao 3D Touch no Xamarin.iOS

Este artigo aborda o uso dos novos gestos do iPhone 6s e iPhone 6s Plus 3D Touch em seu aplicativo.

Exemplos de aplicativos habilitados para 3D Touch

Este artigo fornecerá uma introdução ao uso das novas APIs 3D Touch para adicionar gestos sensíveis à pressão aos seus aplicativos Xamarin.iOS que estão sendo executados nos novos dispositivos iPhone 6s e iPhone 6s Plus.

Com o 3D Touch, um aplicativo para iPhone agora é capaz de não apenas dizer que o usuário está tocando na tela do dispositivo, mas também é capaz de sentir quanta pressão o usuário está exercendo e responder aos diferentes níveis de pressão.

O 3D Touch fornece os seguintes recursos ao seu aplicativo:

  • Sensibilidade à pressão - Os aplicativos agora podem medir o quão duro ou leve o usuário está tocando na tela e aproveitar essas informações. Por exemplo, um aplicativo de pintura pode tornar uma linha mais grossa ou mais fina com base na intensidade com que o usuário está tocando na tela.
  • Peek and Pop - Seu aplicativo agora pode permitir que o usuário interaja com seus dados sem precisar navegar para fora do contexto atual. Ao pressionar fortemente a tela na tela, eles podem espiar o item em que estão interessados (como visualizar uma mensagem). Ao pressionar mais, eles podem aparecer no item.
  • Ações Rápidas - Pense nas Ações Rápidas, como os menus contextuais que podem ser exibidos quando um usuário clica com o botão direito do mouse em um item em um aplicativo da área de trabalho. Usando as Ações Rápidas, você pode adicionar atalhos às funções em seu aplicativo diretamente do ícone do aplicativo na tela inicial.
  • Testando o 3D Touch no simulador - Com o hardware Mac correto, você pode testar aplicativos habilitados para 3D Touch no simulador do iOS.

Sensibilidade à pressão

Como dito acima, usando novas propriedades da classe UITouch você pode medir a quantidade de pressão que o usuário está aplicando na tela do dispositivo iOS e usar essas informações em sua interface de usuário. Por exemplo, tornar uma pincelada mais translúcida ou opaca com base na quantidade de pressão.

Uma pincelada renderizada como mais translúcida ou opaca com base na quantidade de pressão

Como resultado do 3D Touch, se o seu aplicativo estiver sendo executado no iOS 9 (ou superior) e o dispositivo iOS for capaz de suportar o 3D Touch, as mudanças na pressão farão com que o TouchesMoved evento seja aumentado.

Por exemplo, ao monitorar o TouchesMoved evento de um UIView, você pode usar o código a seguir para obter a pressão atual que o usuário está aplicando à tela:

public override void TouchesMoved (NSSet touches, UIEvent evt)
{
    base.TouchesMoved (touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        // Get the pressure
        var force = touch.Force;
        var maxForce = touch.MaximumPossibleForce;

        // Do something with the touch and the pressure
        ...
    }
}

A MaximumPossibleForce propriedade retorna o valor mais alto possível para a Force propriedade do UITouch com base no dispositivo iOS no qual o aplicativo está sendo executado.

Importante

Mudanças na pressão farão com que o TouchesMoved evento seja aumentado, mesmo que as coordenadas X/Y não tenham sido alteradas. Devido a essa mudança de comportamento, seus aplicativos iOS devem estar preparados para que o TouchesMoved evento seja invocado com mais frequência e para que as coordenadas X/Y sejam as mesmas da última TouchesMoved chamada.

Para obter mais informações, consulte TouchCanvas da Apple: Usando o aplicativo de exemplo UITouch de forma eficiente e eficaz e Referência de classe UITouch.

Espreitar e Pop

O 3D Touch oferece novas maneiras para um usuário interagir com informações em seu aplicativo mais rápido do que nunca, sem precisar navegar de sua localização atual.

Por exemplo, se o aplicativo estiver exibindo uma tabela de mensagens, o usuário poderá pressionar com força um item para visualizar seu conteúdo em uma exibição de sobreposição (que a Apple chama de Espiada).

Um exemplo de espreitar o conteúdo

Se o usuário pressionar mais, ele entrará na exibição de mensagem normal (que é conhecida como Pop-ping na exibição).

Verificando a disponibilidade do 3D Touch

Ao trabalhar com um UIViewController você pode usar o seguinte código para ver se o dispositivo iOS em que o aplicativo está sendo executado suporta 3D Touch:

public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
{
    //Important: call the base function
    base.TraitCollectionDidChange(previousTraitCollection);

    //See if the new TraitCollection value includes force touch
    if (TraitCollection.ForceTouchCapability == UIForceTouchCapability.Available) {
        //Do something with 3D touch, for instance...
        RegisterForPreviewingWithDelegate (this, View);
        ...

Este método pode ser chamado antes ou depoisViewDidLoad().

Lidando com Peek e Pop

Em um dispositivo iOS que pode lidar com o 3D Touch, podemos usar uma instância da UIViewControllerPreviewingDelegate classe para lidar com a exibição de detalhes do item Peek e Pop . Por exemplo, se tivéssemos um Controlador de Exibição de Tabela chamado MasterViewController , poderíamos usar o seguinte código para oferecer suporte a Peek e Pop:

using System;
using System.Collections.Generic;
using UIKit;
using Foundation;
using CoreGraphics;

namespace DTouch
{
    public class PreviewingDelegate : UIViewControllerPreviewingDelegate
    {
        #region Computed Properties
        public MasterViewController MasterController { get; set; }
        #endregion

        #region Constructors
        public PreviewingDelegate (MasterViewController masterController)
        {
            // Initialize
            this.MasterController = masterController;
        }

        public PreviewingDelegate (NSObjectFlag t) : base(t)
        {
        }

        public PreviewingDelegate (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        /// Present the view controller for the "Pop" action.
        public override void CommitViewController (IUIViewControllerPreviewing previewingContext, UIViewController viewControllerToCommit)
        {
            // Reuse Peek view controller for details presentation
            MasterController.ShowViewController(viewControllerToCommit,this);
        }

        /// Create a previewing view controller to be shown at "Peek".
        public override UIViewController GetViewControllerForPreview (IUIViewControllerPreviewing previewingContext, CGPoint location)
        {
            // Grab the item to preview
            var indexPath = MasterController.TableView.IndexPathForRowAtPoint (location);
            var cell = MasterController.TableView.CellAt (indexPath);
            var item = MasterController.dataSource.Objects [indexPath.Row];

            // Grab a controller and set it to the default sizes
            var detailViewController = MasterController.Storyboard.InstantiateViewController ("DetailViewController") as DetailViewController;
            detailViewController.PreferredContentSize = new CGSize (0, 0);

            // Set the data for the display
            detailViewController.SetDetailItem (item);
            detailViewController.NavigationItem.LeftBarButtonItem = MasterController.SplitViewController.DisplayModeButtonItem;
            detailViewController.NavigationItem.LeftItemsSupplementBackButton = true;

            // Set the source rect to the cell frame, so everything else is blurred.
            previewingContext.SourceRect = cell.Frame;

            return detailViewController;
        }
        #endregion
    }
}

O GetViewControllerForPreview método é usado para executar a operação Peek . Ele obtém acesso à célula da tabela e aos dados de suporte e, em seguida, carrega o DetailViewController do Storyboard atual. Ao definir o PreferredContentSize como (0,0), estamos solicitando o tamanho padrão do modo de exibição Peek . Finalmente, desfocamos tudo, menos a célula com a qual previewingContext.SourceRect = cell.Frame estamos exibindo e retornamos a nova exibição para exibição.

O CommitViewController reutiliza o modo de exibição que criamos no modo de exibição Espiar para o modo de exibição Pop quando o usuário pressiona mais.

Registrando-se para Peek e Pop

A partir do View Controller do qual queremos permitir que o usuário espie e Pop itens, precisamos nos registrar para este serviço. No exemplo dado acima de um Table View Controller (MasterViewController), usaríamos o seguinte código:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    // Check to see if 3D Touch is available
    if (TraitCollection.ForceTouchCapability == UIForceTouchCapability.Available) {
        // Register for Peek and Pop
        RegisterForPreviewingWithDelegate(new PreviewingDelegate(this), View);
    }
    ...

}

Aqui estamos chamando o RegisterForPreviewingWithDelegate método com uma instância do PreviewingDelegate que criamos acima. Em dispositivos iOS que suportam o 3D Touch, o usuário pode pressionar com força um item para espiá-lo. Se eles pressionarem ainda mais, o item aparecerá na exibição padrão.

Para obter mais informações, consulte ViewControllerPreviews: Using the UIViewController previewing APIs sample app, UIPreviewAction Class Reference, UIPreviewActionGroup Class Reference e UIPreviewActionItem Protocol Reference.

Ações Rápidas

Usando o 3D Touch e as Ações Rápidas, você pode adicionar atalhos comuns, rápidos e fáceis de acessar às funções em seu aplicativo a partir do ícone da tela inicial no dispositivo iOS.

Como dito acima, você pode pensar em Ações Rápidas, como os menus contextuais que podem ser exibidos quando um usuário clica com o botão direito do mouse em um item em um aplicativo da área de trabalho. Você deve usar as Ações Rápidas para fornecer atalhos para as funções ou recursos mais comuns do seu aplicativo.

Um exemplo de um menu Ações Rápidas

Definindo ações rápidas estáticas

Se uma ou mais das Ações Rápidas exigidas pelo seu aplicativo forem estáticas e não precisarem ser alteradas, você poderá defini-las no arquivo do Info.plist aplicativo. Edite este arquivo em um editor externo e adicione as seguintes chaves:

<key>UIApplicationShortcutItems</key>
<array>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeSearch</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Will search for an item</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Search</string>
        <key>UIApplicationShortcutItemType</key>
        <string>com.company.appname.000</string>
    </dict>
    <dict>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeShare</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Will share an item</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Share</string>
        <key>UIApplicationShortcutItemType</key>
        <string>com.company.appname.001</string>
    </dict>
</array>

Aqui estamos definindo dois itens estáticos de Ação Rápida com as seguintes chaves:

  • UIApplicationShortcutItemIconType - Define o ícone que será exibido pelo item Ação Rápida como um dos seguintes valores:

    • UIApplicationShortcutIconTypeAdd
    • UIApplicationShortcutIconTypeAlarm
    • UIApplicationShortcutIconTypeAudio
    • UIApplicationShortcutIconTypeBookmark
    • UIApplicationShortcutIconTypeCapturePhoto
    • UIApplicationShortcutIconTypeCaptureVideo
    • UIApplicationShortcutIconTypeCloud
    • UIApplicationShortcutIconTypeCompose
    • UIApplicationShortcutIconTypeConfirmation
    • UIApplicationShortcutIconTypeContact
    • UIApplicationShortcutIconTypeDate
    • UIApplicationShortcutIconTypeFavorite
    • UIApplicationShortcutIconTypeHome
    • UIApplicationShortcutIconTypeInvitation
    • UIApplicationShortcutIconTypeLocation
    • UIApplicationShortcutIconTypeLove
    • UIApplicationShortcutIconTypeMail
    • UIApplicationShortcutIconTypeMarkLocation
    • UIApplicationShortcutIconTypeMessage
    • UIApplicationShortcutIconTypePause
    • UIApplicationShortcutIconTypePlay
    • UIApplicationShortcutIconTypeProhibit
    • UIApplicationShortcutIconTypeSearch
    • UIApplicationShortcutIconTypeShare
    • UIApplicationShortcutIconTypeShuffle
    • UIApplicationShortcutIconTypeTask
    • UIApplicationShortcutIconTypeTaskCompleted
    • UIApplicationShortcutIconTypeTime
    • UIApplicationShortcutIconTypeUpdate

    Imagens UIApplicationShortcutIconType

  • UIApplicationShortcutItemSubtitle - Define o subtítulo do item.

  • UIApplicationShortcutItemTitle - Define o título do item.

  • UIApplicationShortcutItemType - É um valor de cadeia de caracteres que usaremos para identificar o item em nosso aplicativo. Consulte a seção a seguir para mais informações.

Importante

Os itens de Info.plist atalho de Ação Rápida definidos no arquivo não podem ser acessados com a Application.ShortcutItems propriedade. Eles só são passados para o manipulador de HandleShortcutItem eventos.

Identificando itens de ação rápida

Como você viu acima, ao definir seus itens de Info.plistAção Rápida no aplicativo , você atribuiu um valor de cadeia de caracteres à UIApplicationShortcutItemType chave para identificá-los.

Para tornar esses identificadores mais fáceis de trabalhar no código, adicione uma classe chamada ShortcutIdentifier ao projeto do seu aplicativo e faça com que ela tenha a seguinte aparência:

using System;

namespace AppSearch
{
    public static class ShortcutIdentifier
    {
        public const string First = "com.company.appname.000";
        public const string Second = "com.company.appname.001";
        public const string Third = "com.company.appname.002";
        public const string Fourth = "com.company.appname.003";
    }
}

Manipulando uma ação rápida

Em seguida, você precisa modificar o arquivo do AppDelegate.cs aplicativo para manipular o usuário selecionando um item de Ação Rápida no ícone do aplicativo na tela inicial.

Faça as seguintes edições:

using System;
...

public UIApplicationShortcutItem LaunchedShortcutItem { get; set; }

public bool HandleShortcutItem(UIApplicationShortcutItem shortcutItem) {
    var handled = false;

    // Anything to process?
    if (shortcutItem == null) return false;

    // Take action based on the shortcut type
    switch (shortcutItem.Type) {
    case ShortcutIdentifier.First:
        Console.WriteLine ("First shortcut selected");
        handled = true;
        break;
    case ShortcutIdentifier.Second:
        Console.WriteLine ("Second shortcut selected");
        handled = true;
        break;
    case ShortcutIdentifier.Third:
        Console.WriteLine ("Third shortcut selected");
        handled = true;
        break;
    case ShortcutIdentifier.Fourth:
        Console.WriteLine ("Forth shortcut selected");
        handled = true;
        break;
    }

    // Return results
    return handled;
}

public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
    var shouldPerformAdditionalDelegateHandling = true;

    // Get possible shortcut item
    if (launchOptions != null) {
        LaunchedShortcutItem = launchOptions [UIApplication.LaunchOptionsShortcutItemKey] as UIApplicationShortcutItem;
        shouldPerformAdditionalDelegateHandling = (LaunchedShortcutItem == null);
    }

    return shouldPerformAdditionalDelegateHandling;
}

public override void OnActivated (UIApplication application)
{
    // Handle any shortcut item being selected
    HandleShortcutItem(LaunchedShortcutItem);

    // Clear shortcut after it's been handled
    LaunchedShortcutItem = null;
}

public override void PerformActionForShortcutItem (UIApplication application, UIApplicationShortcutItem shortcutItem, UIOperationHandler completionHandler)
{
    // Perform action
    completionHandler(HandleShortcutItem(shortcutItem));
}

Primeiro, definimos uma propriedade pública LaunchedShortcutItem para rastrear o último item de Ação Rápida selecionado pelo usuário. Em seguida, substituímos o FinishedLaunching método e vemos se launchOptions foram passados e se eles contêm um item de Ação Rápida. Se o fizerem, armazenamos a LaunchedShortcutItem Ação Rápida na propriedade.

Em seguida, substituímos o OnActivated método e passamos qualquer item de Início Rápido selecionado para o HandleShortcutItem método a ser acionado. No momento, estamos apenas escrevendo uma mensagem para o Console. Em um aplicativo real, você lidaria com qualquer ação necessária. Após a ação ter sido tomada, a LaunchedShortcutItem propriedade é liberada.

Finalmente, se seu aplicativo já estava em execução, o PerformActionForShortcutItem método seria chamado para manipular o item de Ação Rápida, então precisamos substituí-lo e chamar nosso HandleShortcutItem método aqui também.

Criando itens dinâmicos de ação rápida

Além de definir itens estáticos de Ação Rápida no arquivo do seu aplicativo, você pode criar Ações Rápidas dinâmicas Info.plist em tempo real. Para definir duas novas Ações Rápidas dinâmicas, edite o AppDelegate.cs arquivo novamente e modifique o FinishedLaunching método para ter a seguinte aparência:

public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
    var shouldPerformAdditionalDelegateHandling = true;

    // Get possible shortcut item
    if (launchOptions != null) {
        LaunchedShortcutItem = launchOptions [UIApplication.LaunchOptionsShortcutItemKey] as UIApplicationShortcutItem;
        shouldPerformAdditionalDelegateHandling = (LaunchedShortcutItem == null);
    }

    // Add dynamic shortcut items
    if (application.ShortcutItems.Length == 0) {
        var shortcut3 = new UIMutableApplicationShortcutItem (ShortcutIdentifier.Third, "Play") {
            LocalizedSubtitle = "Will play an item",
            Icon = UIApplicationShortcutIcon.FromType(UIApplicationShortcutIconType.Play)
        };

        var shortcut4 = new UIMutableApplicationShortcutItem (ShortcutIdentifier.Fourth, "Pause") {
            LocalizedSubtitle = "Will pause an item",
            Icon = UIApplicationShortcutIcon.FromType(UIApplicationShortcutIconType.Pause)
        };

        // Update the application providing the initial 'dynamic' shortcut items.
        application.ShortcutItems = new UIApplicationShortcutItem[]{shortcut3, shortcut4};
    }

    return shouldPerformAdditionalDelegateHandling;
}

Agora estamos verificando se o application já contém um conjunto de criados ShortcutItemsdinamicamente, se não o fizer, criaremos dois novos UIMutableApplicationShortcutItem objetos para definir os novos itens e adicioná-los à ShortcutItems matriz.

O código que já adicionamos na seção Manipulando uma Ação Rápida acima manipulará essas Ações Rápidas dinâmicas da mesma forma que as estáticas.

Deve-se notar que você pode criar uma mistura de itens de Ação Rápida estáticos e dinâmicos (como estamos fazendo aqui), você não está limitado a um ou outro.

Para obter mais informações, consulte ApplicationShortcuts : Using UIApplicationShortcutItem sample app, UIApplicationShortcutItem Class Reference, UIMutableApplicationShortcutItem Class Reference e UIApplicationShortcutIcon Class Reference.

Testando o 3D Touch no simulador

Ao usar a versão mais recente do Xcode e do iOS Simulator em um Mac compatível com um trackpad de ativação Force Touch, você pode testar a funcionalidade 3D Touch no Simulator.

Para ativar essa funcionalidade, execute qualquer aplicativo no hardware simulado do iPhone que suporte 3D Touch (iPhone 6s e superior). Em seguida, selecione o menu Hardware no Simulador iOS e ative o item de menu Usar Força do Trackpad para toque 3D:

Selecione o menu Hardware no Simulador do iOS e ative o item de menu Usar força do trackpad para toque 3D

Com este recurso ativo, você pode pressionar mais o trackpad do Mac para ativar o 3D Touch, assim como faria no hardware real do iPhone.

Resumo

Este artigo apresentou as novas APIs 3D Touch disponibilizadas no iOS 9 para o iPhone 6s e iPhone 6s Plus. Ele cobriu a adição de sensibilidade à pressão a um aplicativo; usar o Peek e o Pop para exibir rapidamente informações no aplicativo do contexto atual sem navegação; e usando as Ações Rápidas para fornecer atalhos para os recursos mais usados do seu aplicativo.