Общие сведения о трехмерном касании в Xamarin.iOS

В этой статье рассматриваются новые жесты iPhone 6s и iPhone 6s Plus 3D Touch в приложении.

Примеры приложений с поддержкой 3D Touch

В этой статье приведены и общие сведения об использовании новых 3D Touch API для добавления чувствительных жестов давления к приложениям Xamarin.iOS, работающим на новых устройствах iPhone 6s и iPhone 6s Plus.

С помощью 3D Touch приложение iPhone теперь может не только сказать, что пользователь касается экрана устройства, но он может понять, сколько давления пользователь оказывает и реагирует на различные уровни давления.

3D Touch предоставляет следующие функции приложения:

  • Конфиденциальность давления . Приложения теперь могут измерять, как трудно или легко пользователя касаться экрана и воспользоваться этой информацией. Например, приложение для рисования может сделать линию толще или тоньше на основе того, насколько сильно пользователь касается экрана.
  • Просмотр и всплывающее окно . Теперь приложение может позволить пользователю взаимодействовать с данными, не переходя из текущего контекста. Нажав кнопку на экране, они могут посмотреть на интересующий элемент (например, предварительный просмотр сообщения). Нажимая кнопку сложнее, они могут всплыть в элемент.
  • Быстрые действия . Думайте о быстрых действиях, таких как контекстные меню, которые можно открыть, когда пользователь щелкает элемент правой кнопкой мыши в классическом приложении. С помощью быстрых действий можно добавлять сочетания клавиш в функции в приложении непосредственно с значка приложения на начальном экране.
  • Тестирование трехмерного сенсорного ввода в симуляторе — с правильным оборудованием Mac можно протестировать приложения с поддержкой 3D Touch в симуляторе iOS.

Чувствительность к давлению

Как описано выше, используя новые свойства класса UITouch , вы можете измерить количество давления, которое пользователь применяет к экрану устройства iOS и использовать эти сведения в пользовательском интерфейсе. Например, создание росчерка кисти более полупрозрачным или непрозрачным на основе количества давления.

Росчерк кисти, отрисованный как более прозрачный или непрозрачный на основе количества давления

В результате 3D Touch, если ваше приложение работает на iOS 9 (или больше), а устройство iOS может поддерживать трехмерный сенсорный ввод, изменения в давлении будут вызваны TouchesMoved событием.

Например, при мониторинге TouchesMoved события UIView можно использовать следующий код, чтобы получить текущее давление, которое пользователь применяет к экрану:

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
        ...
    }
}

Свойство MaximumPossibleForce возвращает максимально возможное значение свойства Force UITouch на основе устройства iOS, на котором запущено приложение.

Внимание

Изменение давления приведет TouchesMoved к возникновению события, даже если координаты X/Y не изменились. Из-за этого изменения поведения приложения iOS должны быть готовы TouchesMoved к вызову события чаще и для координат X/Y, которые будут совпадать с последним TouchesMoved вызовом.

Дополнительные сведения см. в статье Apple TouchCanvas: использование UITouch эффективно и эффективно примеров приложения и справочника по классу UITouch.

Просмотр и поп

3D Touch предоставляет новые способы взаимодействия пользователя с информацией в приложении быстрее, чем когда-либо, без необходимости переходить из текущего расположения.

Например, если приложение отображает таблицу сообщений, пользователь может нажать на элемент, чтобы предварительно просмотреть его содержимое в представлении наложения (что Apple называется просмотром).

Пример просмотра содержимого

Если пользователь нажимает труднее, он введет регулярное представление сообщений (которое называется pop-ping в представлении).

Проверка доступности трехмерного сенсорного ввода

При работе с UIViewController кодом можно использовать следующий код, чтобы узнать, работает ли приложение на устройстве iOS, на котором поддерживается 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);
        ...

Этот метод может вызываться до или послеViewDidLoad().

Обработка всплывающих и всплывающих окон

На устройстве iOS, которое может обрабатывать трехмерный сенсорный ввод, можно использовать экземпляр класса для обработки отображения сведений UIViewControllerPreviewingDelegate о элементе Peek и Pop . Например, если у нас был контроллер представления таблиц, который называется MasterViewController , можно использовать следующий код для поддержки Peek и 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
    }
}

Метод GetViewControllerForPreview используется для выполнения операции "Просмотр ". Он получает доступ к ячейке таблицы и резервным данным, а затем загружается DetailViewController из текущей раскадровки. Задав PreferredContentSize значение (0,0), мы запрашиваем размер представления по умолчанию. Наконец, мы размытием все, кроме ячейки, с которыми мы отображаем previewingContext.SourceRect = cell.Frame , и мы возвращаем новое представление для отображения.

Повторно CommitViewController использует представление, созданное в представлении Pop, когда пользователь нажимает кнопку "Сложнее".

Регистрация для просмотра и pop

С контроллера представления, из которого мы хотим разрешить пользователю просматривать и всплывающие элементы, нам нужно зарегистрировать эту службу. В приведенном выше примере контроллера представления таблиц (MasterViewController) мы будем использовать следующий код:

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);
    }
    ...

}

Здесь мы вызываем RegisterForPreviewingWithDelegate метод с экземпляром созданного выше экземпляра PreviewingDelegate . На устройствах iOS, поддерживающих 3D Touch, пользователь может нажать на элемент, чтобы просмотреть его. Если они нажимают еще труднее, элемент будет отображаться в стандартном представлении отображения.

Дополнительные сведения см. в статье ViewControllerPreviews Apple: использование примера API-интерфейсов UIViewController для предварительного просмотра API, справочник по классу UIPreviewActionAction, справочник по классу UIPreviewActionGroup и справочник по протоколу UIPreviewActionItem.

Быстрые действия

Используя 3D Touch и быстрые действия, вы можете добавить общие, быстрые и простые сочетания клавиш для функций в приложении с помощью значка начального экрана на устройстве iOS.

Как упоминалось выше, вы можете подумать о быстрых действиях, таких как контекстные меню, которые можно открыть, когда пользователь щелкает элемент правой кнопкой мыши в классическом приложении. Для предоставления ярлыков наиболее распространенным функциям или функциям приложения следует использовать быстрые действия.

Пример меню

Определение статических быстрых действий

Если одно или несколько быстрых действий, необходимых вашему приложению, являются статическими и не нужно изменять их, их можно определить в файле приложения Info.plist . Измените этот файл во внешнем редакторе и добавьте следующие ключи:

<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>

Здесь мы определим два статических элемента быстрого действия со следующими ключами:

  • UIApplicationShortcutItemIconType — Определяет значок, который будет отображаться элементом быстрого действия в качестве одного из следующих значений:

    • 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

    Imagery UIApplicationShortcutIconType

  • UIApplicationShortcutItemSubtitle — определяет подзаголовок элемента.

  • UIApplicationShortcutItemTitle — определяет заголовок элемента.

  • UIApplicationShortcutItemType — строковое значение, которое мы будем использовать для идентификации элемента в нашем приложении. См. дополнительные сведения в следующем разделе.

Внимание

С помощью свойства невозможно получить доступ к Application.ShortcutItems элементам ярлыка быстрого действия, заданным в Info.plist файле. Они передаются только обработчику HandleShortcutItem событий.

Определение элементов быстрого действия

Как вы видели выше, когда вы определили элементы быстрого действия в приложении Info.plist, вы назначили строковое значение ключу UIApplicationShortcutItemType для их идентификации.

Чтобы упростить работу с этими идентификаторами в коде, добавьте класс, вызываемый ShortcutIdentifier в проект приложения, и сделайте его следующим образом:

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

Обработка быстрого действия

Затем необходимо изменить файл приложения AppDelegate.cs , чтобы обработать элемент быстрого действия пользователя, щелкнув элемент быстрого действия на начальном экране приложения.

Внесите следующие правки:

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

Сначала мы определяем общедоступное LaunchedShortcutItem свойство для отслеживания последнего выбранного элемента быстрого действия пользователем. Затем мы переопределим FinishedLaunching метод и узнаем launchOptions , были ли переданы и содержат ли они элемент быстрого действия. Если они делают, мы храним быстрое действие в свойстве LaunchedShortcutItem .

Затем переопределите OnActivated метод и передайте любой выбранный элемент быстрого запуска методу HandleShortcutItem , который будет выполняться. В настоящее время мы пишем только сообщение в консоль. В реальном приложении вы будете обрабатывать все необходимые действия. После выполнения LaunchedShortcutItem действия свойство очищается.

Наконец, если приложение уже запущено, метод будет вызван для обработки элемента быстрого действия, PerformActionForShortcutItem поэтому нам нужно переопределить его и вызвать здесь HandleShortcutItem наш метод.

Создание элементов динамического быстрого действия

Помимо определения статических элементов быстрого действия в файле приложения Info.plist , вы можете создавать динамические быстрые действия. Чтобы определить два новых динамических быстрых действия, измените AppDelegate.cs файл еще раз и измените FinishedLaunching метод, чтобы выглядеть следующим образом:

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;
}

Теперь мы проверяем, содержит ли application уже набор динамически созданного ShortcutItemsнабора, если он не создаст два новых объекта, чтобы определить новые UIMutableApplicationShortcutItem элементы и добавить их в ShortcutItems массив.

Приведенный выше код, который мы уже добавили в разделе "Обработка быстрого действия", будет обрабатывать эти динамические быстрые действия так же, как статические.

Следует отметить, что можно создать смесь статических и динамических элементов быстрого действия (как мы делаем здесь), вы не ограничены одним или другим.

Дополнительные сведения см. в разделе ApplicationShortcuts Apple: использование примера приложения UIApplicationShortcutItem, справочник по классу UIApplicationShortcutItem, UIMutableApplicationShortcutItem Class Reference и UIApplicationShortcutIcon Class Reference.

Тестирование трехмерного касания в симуляторе

При использовании последней версии Xcode и симулятора iOS на совместимом Mac с power Force Touch включите трекпад, вы можете протестировать функции 3D Touch в симуляторе.

Чтобы включить эту функцию, запустите любое приложение в имитированном оборудовании iPhone, которое поддерживает 3D Touch (iPhone 6s и больше). Затем выберите меню "Оборудование" в симуляторе iOS и включите команду Use Trackpad Force for 3D touch menu item:

Выберите меню

С помощью этой функции вы можете нажать труднее на трекпад Mac, чтобы включить 3D Touch так же, как и на реальном оборудовании iPhone.

Итоги

В этой статье представлены новые 3D Touch API, доступные в iOS 9 для iPhone 6s и iPhone 6s Plus. Он охватывал добавление чувствительности давления к приложению; с помощью peek и Pop для быстрого отображения сведений в приложении из текущего контекста без навигации; и использование быстрых действий для предоставления ярлыков наиболее часто используемых функций приложения.