Xamarin.iOS 中的 3D Touch 简介
本文介绍如何在应用中使用新的 i电话 6s 和 i电话 6s Plus 3D 触控手势。
本文介绍如何使用新的 3D Touch API 为在新 iPhone 6s 和 iPhone 6s Plus 设备上运行的 Xamarin.iOS 应用添加压力敏感手势。
使用 3D Touch 时,i电话 应用现在不仅能够告知用户正在触摸设备的屏幕,而且能够感知用户施加的压力,并响应不同的压力级别。
3D Touch 为应用提供以下功能:
- 压力感应 - 应用现在可以测量用户触摸屏幕的力度并利用该信息。 例如,绘画应用可以根据用户触摸屏幕的力度来使线条变粗或变细。
- 轻瞄和突显 - 应用现在可以让用户与其数据交互,而无需离开当前上下文。 通过在屏幕上按硬键,他们可以查看他们感兴趣的项目(如预览消息)。 通过更努力地按下,他们可以弹出项。
- 快速操作 - 将快速操作想象为上下文菜单,当用户右键单击桌面应用中的项时,可以弹出这些菜单。 使用快速操作,可以直接从主屏幕上的应用图标向应用中的函数添加快捷方式。
- 在模拟器 中测试 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 触控可用性
使用 A UIViewController
时,可以使用以下代码查看应用是否在 3D Touch 上运行的 iOS 设备:
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
用于执行 速览 操作。 它获取对表单元格和支持数据的访问权限,然后从当前情节提要加载 DetailViewController
数据。 通过设置 PreferredContentSize
到 (0,0),我们要求使用默认 的“速览 ”视图大小。 最后,我们模糊显示 previewingContext.SourceRect = cell.Frame
的所有单元格,并返回用于显示的新视图。
当用户更努力地按下时,将CommitViewController
重复使用我们在 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 设备上的主屏幕图标添加常用、快速且易于访问应用中函数的快捷方式。
如上所述,可以将快速操作视为上下文菜单,当用户右键单击桌面应用中的某个项时,可以弹出这些菜单。 应使用快速操作来提供应用的最常见函数或功能的快捷方式。
定义静态快速操作
如果应用的一个或多个快速操作是静态的,并且不需要更改,则可以在应用的 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
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 模拟器中的“硬件”菜单,并为 3D 触摸菜单项启用“使用触控板强制”:
如果此功能处于活动状态,可以在 Mac 的触控板上更努力地按下,以像在实际 i电话 硬件上一样启用 3D Touch。
总结
本文介绍了 iOS 9 中为 i电话 6s 和 i电话 6s Plus 提供的新 3D 触控 API。 其中介绍了向应用添加压力敏感度;使用“速览”和“弹出”快速显示当前上下文中的应用内信息,而无需导航;使用快速操作提供应用最常用的功能的快捷方式。