iOS
Swift
3DTouch

ViewControllerの3DTouch、Peek&Popを導入

ViewControllerの3DTouch画面遷移、Peek&Popの実装について。
下記サンプルを作成。

開発環境

Mac OS High Sierra 10.13.3
Xcode 9.3
Swift 4

作ったもの

  • MainVC -> SecondVCへの画面遷移する「次へ」ボタンについて、Peek&Popを導入

Peek&Popサンプル実装_改.gif

事前準備:MainVC -> SecondVC への画面遷移

MainVC.swift

class MainVC: UIViewController {

    @IBOutlet weak var nextButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func nextButtonAction(_ sender: Any) {
        transitionToSecondVC()
    }

    func transitionToSecondVC() {
        self.performSegue(withIdentifier: "toSecondVC", sender: nil)
    }

SecondVC.swift

class SecondVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func CloseButtonAction(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}

Main.storyboard

注意ポイント:

  • MainVC -> SecondVC間を紐付け、identifierを設定
  • SecondVCのStoryboard Identifierを設定

storyboard.png

Peek&Pop設定

MainVC.swift

  • registerForPreviewing でPeek&Popを有効化する
  • UIViewControllerPreviewingDelegate を継承し、2つの previewingContext を定義
class MainVC: UIViewController, UIViewControllerPreviewingDelegate {

    override func viewDidLoad() {
        ...
        // 3DTouch対応端末かどうか判定して、Peek&Popを有効化
        if self.traitCollection.forceTouchCapability == UIForceTouchCapability.available {
            self.registerForPreviewing(with: self, sourceView: self.view)
        }
    }

    // Peek時アクション
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        // 押下している範囲がボタン内かどうか判定
        let point: CGPoint = nextButton.convert(location, from: self.view)
        guard point.x > 0, point.x < nextButton.bounds.width, point.y > 0, point.y < nextButton.bounds.height else {
            return nil
        }

        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let secondVC = storyBoard.instantiateViewController(withIdentifier: "SecondVC")
        return secondVC
    }

    // Pop時アクション
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        transitionToSecondVC()
    }
}

SecondVC.swift

  • peek時のアクションボタンを設定(peekして上にスワイプした際に表示されるボタン)
class SecondVC: UIViewController {

    // peek時のアクションボタン設定
    override var previewActionItems: [UIPreviewActionItem] {
        get {
            let backAction = UIPreviewAction(title: "戻る", style: .default) { _, _ in
                self.dismiss(animated: true, completion: nil)
            }
            return [backAction]
        }
    }
}

注意点

  • peek時のアクションボタン設定について、遷移前じゃなくて遷移後のViewControllerに設定しないと。

まとめ

previewActionItems の設定が、以前は、

override func previewActionItems() -> [UIPreviewActionItem] {}

という形式だったので注意が必要そうです。