読者です 読者をやめる 読者になる 読者になる

アニメイトラボ開発者ブログ

株式会社アニメイトラボの開発者ブログです


アニメイトラボ開発者ブログ

developer.animatelab.com


UXを意識した3D Touch(Peek & Pop)対応の考察とその実装例

iPhone Swift iOS

TL;DR

  • 今年のiPhoneのハードウェア面のウリは3D Touch
  • Peek & Popはとても簡単に実装できる
  • Peekで見せるViewはPopで表示されるViewと同じである必要はないので、専用のViewControllerを用意するとUXの向上が期待できる、はず

どうも、こんにちは。iOS大好き monoqlo(ものくろ) です。

2015年を振り返ってみると、ここ数年噂されていたApple Watchが発売されたり、iOSベースのtvOSを搭載した第4世代Apple TVが登場したり、Swiftも予定通りオープンソース化されました。

Appleが仕込んできた新しいプロダクトやツールが次々とお披露目された印象深い年となりましたね。

さて、そんな中、毎年アップグレードされるiPhoneですが、今年の目玉のひとつは3D Touchです。

f:id:monoqlo:20151215141504j:plain 引用元:iPhone 6s - デザイン - Apple(日本) http://www.apple.com/jp/iphone-6s/design/ (2015年12月15日)

発表時、「便利な気もするけれど、必要なんだろうか」というような、なんとも腑に落ちない感じの感想を頂いた方々がいたような気もしますが、今月LINEが3D Touchに対応して、未読のままメッセージが読める!と話題になった*1ことで見方が変わった人も多くいるのではないでしょうか(?)

賛否両論ありますが、とにかく実装してみたくなるのが開発者のサガってやつですね!

この記事は animateLAB Advent Calendar 2015 21日目の記事です。

3D Touch対応するなら、まずはここから

3D Touch対応にあたり、オススメなのが、Home Screen Quick ActionsとPeek & Popです。

Home Screen Quick Actionsを実装すると、ホーム画面でアプリアイコンを強く押すことでメニューが表示されます。このメニューがアプリ内の特定の画面を直接表示するショートカットになっています。
例えば、投稿画面や検索画面へのショートカットがよく実装されている印象を受けます。

f:id:monoqlo:20151215141840j:plain 引用元:iPhone 6s - 3D Touch - Apple(日本) http://www.apple.com/jp/iphone-6s/design/ (2015年12月15日)

一方、Peek & Popはアプリ内のお話になります。AppleのアプリではメールやSafariが代表的でしょうか。画面遷移せずに届いたメールの内容やリンク先のWebページをチラ見できます。

f:id:monoqlo:20151215141848j:plain 引用元:iPhone 6s - 3D Touch - Apple(日本) http://www.apple.com/jp/iphone-6s/design/ (2015年12月15日)

Peek & Pop を実装してみよう

今回は、触って楽しい見て楽しいPeek & Popを実装してみましょう。

とはいえ、Appleからシンプルなサンプルプログラムが提供されています*2し、すでに他所のブログ等で実装方法を拝見されている方が多いと思います。

そこで、この記事では実装方法については要所を押さえるにとどめて、UXの観点からPeek & Popの効果的な使い方について考察してみたいと思います。

アニマートでのPeek & Pop

実際に、Peek & Popを実装した弊社のアニメグッズ専門フリマiOSアプリ「アニマート」を例に解説していきます。

f:id:monoqlo:20151215134213j:plain

アニマートでは、起動後に表示されるホーム画面の各タブ内コンテンツでPeek & Popを体験できます。Peek中のクイックアクションについては、一部実装しているものの現在は公開していないので、純粋にチラ見機能ということになります。

f:id:monoqlo:20151215135536j:plain

実装は意外とかんたん!

例えば、スレッド(掲示板)のPeek & Popのために必要なコードはこれだけです*3

class BoardThreadResultsViewController: UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if self.traitCollection.forceTouchCapability == .Available {
            self.registerForPreviewingWithDelegate(self, sourceView: self.tableView)
        }
    }
    
    // 諸々省略
}


extension BoardThreadResultsViewController: UIViewControllerPreviewingDelegate {
    
    func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        guard let indexPath = self.tableView.indexPathForRowAtPoint(location),
            cell = self.tableView.cellForRowAtIndexPath(indexPath) else { return nil }
        
        previewingContext.sourceRect = cell.frame
        return ThreadDetailViewController(thread: self.threads[indexPath.row])
    }
    
    func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
        self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
    }
}

実装について少し解説します。

Peek & Pop機能を使うには、対応させたい UIViewControllerviewDidLoadregisterForPreviewingWithDelegate:sourceView: を実行し、 UIViewControllerPreviewingDelegate に適合する任意のインスタンスとPeekに対応するViewを登録します。

併せて、 UIViewControllerPreviewingDelegate プロトコルの以下のメソッドを実装しておきます。

  • previewingContext:viewControllerForLocation:
  • previewingContext:commitViewController:
previewingContext:viewControllerForLocation:

previewingContext:viewControllerForLocation: は、 registerForPreviewingWithDelegate:sourceView: で登録したViewがタッチイベントを拾った際に実行されます。

引数の location: CGPoint でタッチ位置が取得できるため、今回のケースでは UITableView 上で相当する NSIndexPath を取得し、そこから UITableViewCellインスタンスを取得しています。

次に、もうひとつの引数である previewingContext: UIViewControllerPreviewingsourceRect: CGRect プロパティに、Peekを発生させる位置とサイズをセットします。
これにより、Peekが発生する箇所以外にブラー効果がかかり、Peek時にふわっと浮いているかのように表示されます。

後は、実際にPeekで表示したい UIViewController を生成して返すようにすれば完了です。

なお、このメソッドnil を返すとPeekされないため、意図的に表示したくない場合や不都合が生じた場合には nil を返すようにします。

previewingContext:commitViewController:

previewingContext:commitViewController: は、Peek時に更に押しこまれ、Popして画面遷移する必要が生じた際に実行されます。

引数の viewControllerToCommit: UIViewController が現在Peek中のインスタンスです。今回のケースではこれをそのまま表示するだけで良いので、 Pushして画面遷移させています。

ちなみにデバッグは・・・

これもすでに結構いろんなところで言及されていますし、Appleのリリースノートにも記載がありますが、現在3D TouchはiOS Simulatorでは使えません。
そのため、デバッグするにはiPhone 6s/6s Plusが必要になります… 早くSimulatorでも対応して欲しいですね。。

ユーザーがもっと喜ぶPeek & Popとは

さて、これで普通に遷移後の画面をPeekさせる方法は分かりました。 このままでも充分に便利ですが、UXという観点から見た時、それは果たして充分でしょうか。もう一歩踏み込んで考えてみたいと思います。

有名アプリのUXを考慮したPeek例

今や芸能人も多数愛用するInstagram*4は、iPhone 6s/6s Plusのリリースに合わせて3D Touch対応アップデートを公開しました。
当時なるほどなーと関心したのですが、各ユーザーの画面をPeekさせると単純にその画面が表示されるのではなく、専用のレイアウトでユーザーがチラ見したい要素だけをしっかり見せているんです。

f:id:monoqlo:20151215135630j:plain

ユーザーが「チラ見したいのはなんなのか」

アニマートではフリマの商品個別画面があるのですが、この画面は上部にでかでかと商品の画像が表示されています。
そのため、この画面をそのままPeekするとチラ見の価値がずいぶん下がってしまいます。

f:id:monoqlo:20151215140437j:plain

ここでユーザー目線に立ってみます。

商品がたくさん並ぶタイムラインでは、商品写真、商品名、値段がわかります。
商品個別画面ではこれらに加えて、商品説明や商品状態、配送料の負担者、発送日の目安、他にも売り手の情報やコメントなどが閲覧できます。

まず、タイムラインで見えている商品写真は必要ありません。大きく分けるとこの3つが必要だと考えました。

  1. 商品状態
  2. 金額(配送料は別なのかどうか)
  3. 配送スケジュール

商品の詳細を知れる説明欄も重要な要素ですが、少なくともチラ見ということを考慮すると、上記に上げた3点よりは優先度が低いと思います。

また、商品の紹介文が長いケースも多いので、Peek画面に収まらないことも意識しなければなりません。

そもそも気になる場合にはPopして詳しく見る、というのがAppleが想定している使い方なので、やはり商品説明の優先度は少し低めに設定したいところです。

以上を踏まえて、アニマートのフリマ商品のPeekでは、次の様な画面を表示することにしました。

f:id:monoqlo:20151215140710p:plain

具体的な実装について

previewingContext:viewControllerForLocation: で返却するPeek用のViewControllerを工夫します。

元々 ItemDetailViewController が存在していたのですが、それとは別に ItemDetailPreviewingViewController を作成し、これをPeekさせるようにしました。

このようにすると previewingContext:commitViewController: の引数である viewControllerToCommit: UIViewController には ItemDetailPreviewingViewControllerインスタンスがセットされているため、これは使いません。

本来表示したい ItemDetailViewControllerインスタンスを生成してPushで遷移させるようにしています。

Peek専用のViewControlelrを用意する際の注意点

Peek専用のViewControlelrを用意することで、UXの向上が期待できます。ですが、注意するべき点があります。

遷移先のViewControllerをそのままPeekさせた場合には、 viewDidLoad が実行されて画面がレンダリングされるので、Pop時にはそのまま表示されます。

ですが、ViewControllerを分けることで、通信が2回必要になる可能性があります。(例えば、画面を表示するために通信が必要な場合)

ユーザーの使用シーンから通信環境を考慮すると、Previewで表示する要素に関してはうまく引き継ぎ、Pop後も表示されているのが理想だと思います。*5

まとめ

ここ最近のApp Storeを見ていると、多くのアプリが次々に3D Touchに対応したアップデートを公開しています。

来年発売される次期iPhoneでももちろん3D Touchが使えるはずなので、できるだけ早いタイミングで実装して感触を掴んでおくに越したことはありません。

その際、本記事で言及したようなPeekを実装すると、ユーザーは少しハッピーになるかもしれないよ、ということを頭の片隅に置いておいてもらえれば幸いです。