Xamarin.iOS での 3D Touch の概要
この記事では、新しい iPhone 6s および iPhone 6s Plus 3D Touch ジェスチャをアプリで使用する方法について説明します。
この記事では、新しい 3D Touch API を使って、新しい iPhone 6s および iPhone 6s Plus デバイス上で実行されている Xamarin.iOS アプリに感圧ジェスチャを追加する方法について説明します。
3D Touch を使うと、iPhone アプリはユーザーがデバイスの画面に触れていることを認識できるだけでなく、ユーザーが加えている圧力の強さを感知し、さまざまな圧力レベルに対応することもできます。
3D Touch は、アプリに次の機能を提供します。
- 感圧性 - アプリは、ユーザーが画面に触れている強弱の程度を測定し、その情報を利用できるようになりました。 たとえば、ペイント アプリは、ユーザーが画面をタッチする強さに基づいて線を太くしたり、細くしたりできます。
- Peek と Pop - ユーザーが現在のコンテキストから移動しなくてもデータを操作できるようになりました。 画面を強く押すと、興味のある項目をクイック表示することができます (メッセージのプレビューなど)。 より強く押すことで、項目にポップ表示することができます。
- クイック アクション - クイック アクションは、ユーザーがデスクトップ アプリで項目を右クリックしたときにポップアップされるコンテキスト メニューのようなものだと考えてください。 クイック アクションを使用すると、ホーム画面のアプリ アイコンから直接、アプリ内の関数にショートカットを追加できます。
- シミュレーターでの 3D Touch のテスト - 正しい Mac ハードウェアを使用して、iOS シミュレーターで 3D Touch 対応アプリをテストできます。
筆圧対応機能
前述のように、UITouch クラスの新しいプロパティを使用すると、ユーザーが iOS デバイスの画面に適用している負荷の量を測定し、ユーザー インターフェイスでこの情報を使用できます。 たとえば、圧力の量に基づいてブラシ ストロークの半透明度を高めたり不透明にしたりします。
3D Touch では、アプリが iOS 9 (またはそれ以上) で実行されていて、iOS デバイスが 3D Touch をサポートできる場合、圧力の変化によって 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
プロパティは、アプリが実行されている iOS デバイスに基づいて、UITouch の Force
プロパティの可能な限り高い値を返します。
重要
圧力が変化すると、X/Y 座標が変更されていなくても TouchesMoved
イベントが発生します。 この動作の変更に伴い、iOS アプリは、TouchesMoved
イベントをより頻繁に呼び出し、X/Y 座標が最後の TouchesMoved
呼び出しと同じになるようにする必要があります。
詳細については、Apple の 「TouchCanvas: UITouch を効率的かつ効果的に」の サンプル アプリと「UITouch クラス リファレンス」を参照してください。
クイック表示とポップ表示
3D Touch は、ユーザーが現在の場所から移動しなくても、アプリ内の情報をこれまで以上に迅速に操作するための新しい方法を提供します。
たとえば、アプリにメッセージのテーブルが表示されている場合、ユーザーはアイテムを強く押して、オーバーレイ ビュー (Apple はクイック表示と呼んでいます) でそのコンテンツをプレビューできます。
ユーザーが強く押すと、通常のメッセージ ビュー (-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);
...
このメソッドは、 または after ViewDidLoad()
の前に呼び出される場合があります。
クイック表示とポップ表示の処理
3D Touch を処理できる iOS デバイスでは、UIViewControllerPreviewingDelegate
クラスのインスタンスを使用して、クイック表示とポップ表示の項目の詳細表示を処理できます。 たとえば、MasterViewController
というテーブル ビュー コントローラーがある場合は、次のコードを使用してピーク表示とポップ表示をサポートできます。
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
はポップ表示ビューのピーク表示で作成したビューを再利用します。
クイック表示とポップ表示の登録
ユーザーが項目をクイック表示およびポップ表示できるようにするビュー コントローラーから、このサービスに登録する必要があります。 上記のテーブル ビュー コントローラー (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 デバイスでは、ユーザーは項目を強く押してクイック表示することができます。 さらに強く押すと、項目は標準の表示ビューにポップ表示されます。
詳細については、Apple の ViewControllerPreviews: UIViewController プレビュー API サンプル アプリの使用、UIPreviewAction クラス リファレンス、UIPreviewActionGroup クラス リファレンス、UIPreviewActionItem プロトコル リファレンスを参照してください。
クイック アクション
3D Touch とクイック アクションを使うと、iOS デバイスのホーム画面アイコンからアプリ内の機能への共通の、すばやく簡単にアクセスできるショートカットを追加できます。
前述のように、クイック アクションは、ユーザーがデスクトップ アプリで項目を右クリックしたときにポップアップされるコンテキスト メニューのようなものだと考えてください。 クイック アクションを使用して、アプリのよく使う機能へのショートカットを提供する必要があります。
静的クイック アクションの定義
アプリに必要な 1 つ以上のクイック アクションが静的であり、変更する必要がない場合は、アプリの 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>
ここでは、次のキーを使用して 2 つの静的なクイック アクション項目を定義します。
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
UIApplicationShortcutItemSubtitle
- 項目の字幕を定義します。UIApplicationShortcutItemTitle
- 項目のタイトルを定義します。UIApplicationShortcutItemType
- アプリ内の項目を識別するために使用する文字列値です。 詳細については、次のセクションを参照してください。
重要
Info.plist
ファイルに設定されているクイック アクションのショートカット項目に Application.ShortcutItems
プロパティを使用してアクセスすることはできません。 これらは 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
のファイルで静的なクイック アクション項目を定義するほかに、動的なクイック アクションを作成することもできます。 2 つの新しい動的クイック アクションを定義するには、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
のセットが既に含まれているかどうを確認します。含まれていない場合は、新しい項目を定義して ShortcutItems
配列に追加する 2 つの新しい UIMutableApplicationShortcutItem
オブジェクトを作成します。
上記の「クイック アクションの処理」セクションで既に追加したコードは、静的なクイック アクションと同様に、これらの動的なクイック アクションを処理します。
(ここで行っているとおり) 静的なクイック アクション項目と動的なクイック アクション項目の両方を組み合わせて作成できることに注意してください。一方の項目だけしか使えないわけではありません。
詳細については、Apple の ApplicationShortcuts: UIApplicationShortcutItem サンプル アプリの使用、UIApplicationShortcutItem クラス リファレンス、UIMutableApplicationShortcutItem クラス リファレンス、UIApplicationShortcutIcon クラス リファレンスを参照してください。
シミュレーターでの 3D Touch のテスト
互換性のある Mac で最新バージョンの Xcode と iOS シミュレーターを Force Touch 対応トラックパッドと共に使用する場合は、シミュレーターで 3D Touch 機能をテストできます。
この機能を有効にするには、3D Touch (iPhone 6s 以降) をサポートするシミュレートされた iPhone ハードウェアでアプリを実行します。 次に、iOS シミュレーターで [ハードウェア] メニューを選択し、[3D タッチ メニュー項目にトラックパッド フォースを使用する] を有効にします。
この機能をアクティブにすると、Mac のトラックパッドを強く押して、実際の iPhone ハードウェアと同じように 3D Touch を有効にすることができます。
まとめ
この記事では、iOS 9 for the iPhone 6s および iPhone 6s Plus で利用できる新しい 3D Touch API について説明しました。 アプリへの圧力感度の追加について説明しました。クイック表示とポップ表示を使用して、ナビゲーションがなくても現在のコンテキストからアプリ内情報をすばやく表示します。クイック アクションを使用して、アプリで最もよく使用される機能へのショートカットを提供します。