iOS APPに3D TOUCH機能を追加|Swiftでユーザー体験を向上させる方法
iOSアプリ開発者向けに、Swiftを使って3D TOUCH機能を実装しユーザー体験を改善。操作の迅速化と直感的な操作感を実現し、アプリの魅力を効果的に向上させる具体的手法を解説。
本記事は AI による翻訳をもとに作成されています。表現が不自然な箇所がありましたら、ぜひコメントでお知らせください。
記事一覧
[廃止予定]ユーザー体験を向上させるために、今すぐあなたのiOSアプリに3D TOUCH機能を追加しましょう(Swift)
iOS 3D TOUCH の応用
[廃止] 2020/06/14
iPhone 11以降のモデルでは3D Touch機能が廃止され、代わりにHaptic Touchが採用されており、実装方法も異なります。
先日、プロジェクト開発の合間に多くのiOSの面白い機能を探求しました: CoreML 、 Vision 、 Notification Service Extension 、Notification Content Extension、Today Extension、Core Spotlight、Share Extension、SiriKit(一部は記事にまとめ済み、その他はお楽しみに🤣)
その中でも今日の主役は:3D Touch機能
この機能は iOS 9/iPhone 7以降 にサポートされ始め、私自身がiPhone 6からiPhone 8に乗り換えて初めてその便利さを実感しました!
3D TouchはAPP内で以下の2つの機能を実装できます:
- Preview ViewController プレビュー機能 — 結婚吧APP
- 3D TouchショートカットAPPショートカット起動機能
最初の項目は最も広く使われ、効果も高いものです(Facebook:ニュースフィードの内容プレビュー、Line:メッセージのチラ見)。二番目のAPPショートカット起動は、現在のデータでは利用者が少ないため、最後に説明します。
1. Preview ViewController プレビュー機能:
機能のデモは上の図1のように、ViewControllerのプレビュー機能をサポートしています。
3D Touchで強く押すと背景がぼやける
3D Touchで強く押すとViewControllerのプレビューウィンドウが表示される
3D Touchで強く押すとViewControllerのプレビューウィンドウが表示され、上にスワイプすると下部にオプションメニューを追加できる
3D Touchで強く押して離すとウィンドウに戻る
3D Touchで強く押してからさらに力を入れて目的のViewControllerに入る
ここでは A:リストウィンドウ 、 B:ターゲットウィンドウ に分けて実装するコードをそれぞれ示します:
B内では現在がプレビューか実際にこの画面に入っているかを判別する方法がないため、まず値を渡すためのProtocolを作成して判定します。
1
2
3
protocol UIViewControllerPreviewable {
var is3DTouchPreview:Bool {get set} // 3D Touchプレビューかどうか
}
これでBの中で以下の判定ができるようになります:
1
2
3
4
5
6
7
8
9
10
class BViewController:UIViewController, UIViewControllerPreviewable {
var is3DTouchPreview:Bool = false
override func viewDidLoad() {
super.viewDidLoad()
if is3DTouchPreview {
// プレビュー画面の場合...例:全画面表示にする、ツールバーを隠す
} else {
// 通常モードの場合はそのまま表示
}
}
A:リストビューは UITableView または UICollectionView です:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class AViewController:UIViewController {
//3D Touch対応のViewを登録
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.forceTouchCapability == .available {
//TableView:
registerForPreviewing(with: self, sourceView: self.TableView)
//CollectionView:
registerForPreviewing(with: self, sourceView: self.CollectionView)
}
}
}
extension AViewController: UIViewControllerPreviewingDelegate {
//3D Touchを離した後の処理
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
//これから直接遷移するため、ViewControllerのプレビューモードパラメータを解除:
if var viewControllerToCommit = viewControllerToCommit as? UIViewControllerPreviewable {
viewControllerToCommit.is3DTouchPreview = false
}
self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
}
//3D TouchのCell位置と表示するViewControllerを制御
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
//現在のタップ位置のindexPath/セルの実体を取得
//TableView:
guard let indexPath = TableView.indexPathForRow(at: location),let cell = TableView.cellForRow(at: indexPath) else { return nil }
//CollectionView:
guard let indexPath = CollectionView.indexPathForItem(at: location),let cell = CollectionView.cellForItem(at: indexPath) else { return nil }
//表示したいViewController
let targetViewController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")
//背景のぼかし時に残す領域(通常はタップ位置)、図1参照
previewingContext.sourceRect = cell.frame
//3D Touchウィンドウのサイズ、デフォルトは自動調整で変更不要
//変更する場合は:targetViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)
//プレビュー中のViewControllerに現在プレビューモードであることを通知:
if var targetViewController = targetViewController as? UIViewControllerPreviewable {
targetViewController.is3DTouchPreview = true
}
//nilを返すと何も動作しない
return nil
}
}
注意してください!3D Touchを有効にするViewの登録は“viewDidLoad”ではなく、traitCollectionDidChange内で行う必要があります(こちらの記事を参照してください)。
どこに追加するかについて、多くのトラブルを経験しました。ネット上の情報ではviewDidLoadに書く場合もあれば、cellForItem内に書く場合もありますが、どちらも時々動作しなかったり、一部のセルだけが動作しない問題が発生しました。
付図1 背景ぼかし保持領域のイメージ図
もし上にスワイプして下にオプションメニューを追加する必要がある場合は、B の中に追加してください。BはB、BはBですよ!
1
2
3
4
5
6
override var previewActionItems: [UIPreviewActionItem] {
let profileAction = UIPreviewAction(title: "店舗情報を見る", style: .default) { (action, viewController) -> Void in
// タップ後の操作
}
return [profileAction]
}
空の配列を返すことで、この機能を使用しないことを示します。
完了!
2. APP ショートカット起動
第一歩
info.plist に UIApplicationShortcutItems パラメータを追加し、タイプは Array に設定する
そして、その中にメニュー項目(Dictionary)を追加し、キーと値の設定は以下の通りです:
[必須] UIApplicationShortcutItemType : 識別文字列で、AppDelegateで判定に使用します
[必須] UIApplicationShortcutItemTitle : オプションのタイトル
UIApplicationShortcutItemSubtitle : オプションのサブタイトル
- UIApplicationShortcutItemIconType : システムアイコンを使用する
参考元は こちらの記事 です。
UIApplicationShortcutItemIconFile : カスタムアイコンを使用(サイズ:35x35、単色)、UIApplicationShortcutItemIconTypeとどちらか一方を使用してください
UIApplicationShortcutItemUserInfo : 追加情報の詳細例 EX: [id:1]
私の設定は上の図の通りです
第二ステップ
AppDelegateに処理用の関数を追加する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
var info = shortcutItem.userInfo
switch shortcutItem.type {
case "searchShop":
//
case "topicList":
//
case "likeWorksPic":
//
case "marrybarList":
//
default:
break
}
completionHandler(true)
}
完了!
結論
APPに3D Touch機能を追加するのは難しくなく、ユーザーにとっても親切に感じられます❤;操作デザインと組み合わせてユーザー体験を向上させることができます;しかし現時点では上述の2つの機能しかなく、iPhone 6s以下やiPad、iPhone XRは3D Touchをサポートしていないため、実際にできる機能はさらに限られています。あくまで補助的に体験を向上させることが主な目的となります。
p.s.
もし細かくテストすると、上記の効果は、CollectionViewのスクロール中に一部の画像が画面外に出ているときに押し込むと、上記の状況が発生することがわかります😅
ご質問やご意見がありましたら、お問い合わせ ください。
Post MediumからZMediumToMarkdownによって変換されました。
本記事は Medium にて初公開されました(こちらからオリジナル版を確認)。ZMediumToMarkdown による自動変換・同期技術を使用しています。

{:target="_blank"}](/assets/1ca246e27273/1*Nl6uz_dA2h13g7PtqSi6aw.gif)



{:target="_blank"}](/assets/1ca246e27273/1*S3dbMWNnTvhdt-NlxAQ2Tw.webp)

