Xamarin.iOS 中的 3D Touch 簡介

本文涵蓋在應用程式中使用新的 i 電話 6s 和 i 電話 6s Plus 3D Touch 手勢。

Examples of 3D Touch enabled apps

本文將介紹如何使用新的 3D Touch API,將壓力敏感手勢新增至在新的 i 電話 6s 和 i 電話 6s Plus 裝置上執行的 Xamarin.iOS 應用程式。

使用 3D Touch 時,i 電話 應用程式現在不僅能夠告訴使用者正在觸碰裝置的螢幕,而且能夠感覺到使用者施加多少壓力,並回應不同的壓力等級。

3D Touch 為您的應用程式提供下列功能:

  • 壓力敏感 度 - 應用程式現在可以測量使用者觸碰螢幕並利用該資訊有多硬或光線。 例如,根據使用者觸碰螢幕的困難程度,繪製應用程式可能會使線條變厚或變薄。
  • 查看和快顯 - 您的應用程式現在可以讓使用者與其數據互動,而不需要流覽其目前的內容。 藉由在畫面上按下硬式按鈕,他們可以窺視他們感興趣的專案(例如預覽訊息)。 藉由更努力地按,他們可以彈出專案。
  • 快速動作 - 以滑鼠右鍵按下傳統型應用程式中的專案時,可以像快捷功能表一樣快速動作。 使用快速動作,您可以直接從主畫面上的應用程式圖示,將快捷方式新增至應用程式中的函式。
  • 在模擬器 中測試 3D Touch - 使用正確的 Mac 硬體,您可以在 iOS 模擬器中測試已啟用 3D 觸控的應用程式。

壓力敏感度

如上所述,藉由使用UITouch類別的新屬性,您可以測量使用者套用至iOS裝置畫面的壓力量,並在您的使用者介面中使用這項資訊。 例如,根據壓力量,使筆刷筆劃更透明或不透明。

A brush stroke rendered as more translucent or opaque based on the amount of pressure

由於 3D Touch,如果您的應用程式在 iOS 9 上執行(或更新版本),且 iOS 裝置能夠支援 3D Touch,壓力的變更會導致 TouchesMoved 引發事件。

例如,監視 UIView 的事件TouchesMoved,您可以使用下列程式代碼來取得使用者套用至畫面的目前壓力:

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會根據應用程式執行時所執行的 iOS 裝置,傳Force回 UITouch 屬性的最高可能值。

重要

壓力的變化會導致 TouchesMoved 事件引發,即使 X/Y 座標尚未變更也一樣。 由於行為變更,您的 iOS 應用程式應該準備好 TouchesMoved 讓事件更頻繁地叫用,而且 X/Y 座標與最後一個 TouchesMoved 呼叫相同。

如需詳細資訊,請參閱 Apple 的 TouchCanvas:有效率且有效率地 使用 UITouch 範例應用程式和 UITouch 類別參考

查看和流行

3D Touch 提供新的方式,讓用戶能夠比以往更快速地與應用程式內的資訊互動,而不需要從其目前位置流覽。

例如,如果您的 app 正在顯示訊息數據表,用戶可以在重疊檢視中強制按下專案來預覽其內容(Apple 稱之為預覽)。

An example of Peeking at content

如果使用者按下較困難,他們將輸入一般訊息檢視(這稱為 檢視中的 Pop-ping)。

檢查 3D Touch 可用性

使用 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()呼叫。

處理查看和 Pop

在可處理 3D Touch 的 iOS 裝置上UIViewControllerPreviewingDelegate,我們可以使用 類別的實例來處理查看Pop 專案詳細數據的顯示。 例如,如果我們有名為 MasterViewController 的數據表檢視控制器,我們可以使用下列程式代碼來支援 查看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 可用來執行 Peek 作業。 它會取得資料表資料格和備份資料的存取權,然後從目前的分鏡文本載入 DetailViewController 。 藉由將 設定 PreferredContentSize 為 (0,0), 我們會要求預設 的 [查看 ] 檢視大小。 最後,我們會模糊我們所顯示的 previewingContext.SourceRect = cell.Frame 單元格,並傳回要顯示的新檢視。

會在CommitViewController使用者更努力地按下時,重複使用我們在 [查看] 中為 Pop 檢視建立檢視。

註冊查看和 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);
    }
    ...

}

在這裡,我們會使用我們上述建立的 PreviewingDelegate 實例來呼叫 RegisterForPreviewingWithDelegate 方法。 在支援 3D Touch 的 iOS 裝置上,用戶可以在專案上按下硬式按鈕來查看它。 如果按得更困難,專案就會進入標準顯示檢視。

如需詳細資訊,請參閱 iOS 9 ApplicationShortcuts 範例和 Apple 的 ViewControllerPreviews:使用 UIViewController 預覽 API 範例應用程式、UIPreviewAction 類別參考UIPreviewActionGroup 類別參考UIPreviewActionItem 通訊協定參考

快速動作

使用 3D 觸控和快速動作,您可以從 iOS 裝置上的主畫面圖示,新增常用、快速且輕鬆地存取應用程式中功能的快捷方式。

如上所述,您可以考慮快速動作,例如當使用者以滑鼠右鍵按鍵按下傳統型應用程式中的專案時,可以彈出的內容功能表。 您應該使用快速動作來提供應用程式最常見函式或功能的快捷方式。

An example of a Quick Actions menu

定義靜態快速動作

如果您的應用程式所需的一或多個快速動作是靜態的,而且不需要變更,您可以在應用程式的 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

    UIApplicationShortcutIconType imagery

  • 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 陣列。

我們在上述處理 快速動作 一節中新增的程式代碼將處理這些動態快速動作,就像靜態動作一樣。

請注意,您可以同時建立靜態和動態快速動作專案的混合專案(如我們在這裡所做的那樣),您不限於其中一個或另一個專案。

如需詳細資訊,請參閱 iOS 9 ViewControllerPreview 範例,並參閱 Apple 的 ApplicationShortcuts:使用 UIApplicationShortcutItem 範例應用程式、UIApplicationShortcutItem 類別參考UIMutableApplicationShortcutItem 類別參考UIApplicationShortcutIcon 類別參考

在模擬器中測試 3D 觸控

在相容 Mac 上使用最新版本的 Xcode 和 iOS 模擬器搭配 Force Touch 啟用軌跡板時,您可以在模擬器中測試 3D Touch 功能。

若要啟用此功能,請在支援 3D Touch(i 電話 6 和更新版本)的模擬 i 電話 硬體中執行任何應用程式。 接下來,選取 iOS 模擬器中的 [硬體 ] 功能表,然後啟用 [ 使用 Trackpad Force for 3D 觸控 ] 功能表項:

Select the Hardware menu in the iOS Simulator and enable the Use Trackpad Force for 3D touch menu item

使用此功能時,您可以更努力地按下 Mac 的軌跡板,以啟用 3D Touch,就像您在真實 i 電話 硬體上一樣。

摘要

本文介紹適用於 i 電話 6s 和 i 電話 6s Plus 的 iOS 9 中提供的新 3D Touch API。 它涵蓋將壓力敏感度新增至應用程式;使用 [查看] 和 [Pop] 從目前內容快速顯示應用程式內資訊,而不需流覽;以及使用快速動作來提供您應用程式最常使用功能的快捷方式。