The Pragmatic Ball boy

iOSを中心にやってる万年球拾いの老害エンジニアメモ

3D Touch Peak, Popの使い方

1. 3D Touchの発火元となるviewの登録

UIViewControllerのregisterForPreviewingWithDelegateというメソッドを使って、3D Touchに反応するViewと、3D Touchが発生した際にハンドリングするdelegateを登録します。

    override func viewDidLoad() {
        super.viewDidLoad()
  
        imageView.userInteractionEnabled = true // imageViewの場合これが必要

        registerForPreviewingWithDelegate(self, sourceView: imageView)
    }

2. UIViewControllerPreviewingDelegateを継承

3D Touchに反応するUIViewControllerにUIViewControllerPreviewingDelegateを継承させます

class ViewController: UIViewController, UIViewControllerPreviewingDelegate {

3. UIViewControllerPreviewingDelegateのメソッドの実装

UIViewControllerPreviewingDelegateの2つのrequiredのメソッドを実装します

previewingContext:viewControllerForLocation: の実装

こちらはpeak(プレビュー画面を表示)に対応します。

この中では、peakで表示するViewControllerをreturnします。

    func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        print("peak")

        let sb = UIStoryboard(name: "Storyboard2", bundle: nil)
        let vc = sb.instantiateInitialViewController()
        vc?.preferredContentSize = CGSize(width: 0, height: 200) // 表示サイズ

        print(previewingContext.sourceRect)

        return vc
    }

peakで表示するサイズはViewControllerのpreferredContentSizeで指定することができます。

previewwingContext.sourceRectは3D Touchした際にblurしない範囲(浮き出る部分)を示しています。 sourceViewがimageViewなどでやる場合は特に指定する必要はないですが、tableviewなどの場合、タッチされたcellの位置が浮き出る感じに表示されたほうがよいので、こういうときはpreviewwingContext.sourceRect = cell.frameという風に設定するのがよいと思われます。

previewingContext:commitViewController: の実装

こちらはpop(プレビュー画面で更に強く押して全画面表示)する際に呼ばれるメソッドです。 このメソッド内でpresentViewControllerやnavigationcontroller.pushViewControllerなどを使って次の画面に遷移させます。 引数のcommitViewControllerはpreviewingContext:viewControllerForLocation: でreturnしたViewControllerです。

このメソッドでなにもしないとpeak画面で更に強く押しても何も起こりません。(消える)

    func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
        print("pop")

        presentViewController(viewControllerToCommit, animated: true) {}
    }

4. プレビューアクションの設定

プレビュー画面で下にスクロールしたら出てくるアクションの設定方法です。

プレビュー表示に使うViewController(previewingContext:viewControllerForLocation:でreturnするViewController)でpreviewActionItems() -> [UIPreviewActionItem]をオーバーライドします。

    override func previewActionItems() -> [UIPreviewActionItem] {
        let action1 = UIPreviewAction(title: "action 1", style: .Default) { (previewAction, viewController) in
            print("action 1")
        }
        let action2 = UIPreviewAction(title: "action 1", style: .Destructive) { (previewAction, viewController) in
            print("action 2")
        }

        let subAction1 = UIPreviewAction(title: "subaction 1", style: .Default) { (previewAction, viewController) in
            print("sub action 1")
        }
        let subAction2 = UIPreviewAction(title: "subaction 2", style: .Default) { (previewAction, viewController) in
            print("sub action 2")
        }
        let groupedActions = UIPreviewActionGroup(title: "Sub Actions…", style: .Default, actions: [subAction1, subAction2] )

        return [action1, action2, groupedActions]
    }