【Swift】iOSで"Inbox by Google"のような遷移を実現する方法

# はじめに
最近メーラーをGmailから[Inbox by Goolge](https://itunes.apple.com/us/app/inbox-by-gmail-new-email-app/id905060486?mt=8)に移行しまして、メール一覧から本文に遷移するアニメーションや本文からメール一覧に戻るアクションが自然で良いと感じたので、それらを容易に扱えるようにする方法を書いていこうと思います。

![sample.gif](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SampleImage/sample.gif?raw=true)

このgifアニメーションは、[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController)([113Stars](https://github.com/szk-atmosphere/SAInboxViewController/stargazers) 2015/09/10)のサンプルになります。

今回はこの[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController)を利用して、Inbox by Googleの遷移を実現していきます。


# インストール方法
## iOS8以降の場合
Cocoapodsからのインストールが可能です。
Podfileに

```
pod "SAInboxViewController"
```

を追記してインストールしてください。

## iOS7の場合
[SAInboxViewControllerの5つのファイル](https://github.com/szk-atmosphere/SAInboxViewController/tree/master/SAInboxViewController)をプロジェクトファイルに追加してください。

# 使用方法
1:  まず、一覧を表示するViewControllerに[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxViewController.swift)を継承させてください。本文を表示するViewControllerには[SAInboxDetailViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxDetailViewController.swift)を継承させてください。StoryboardやXibでViewControllerを使用する場合は、それらのClassをSAInboxViewControllerにするのも忘れないでください。

```swift
class FeedViewController: SAInboxViewController {
}

class DetailViewController: SAInboxDetailViewController {
}
```

2: UINavigationControllerを使用して遷移をさせるため、任意の場所にUINavigationControllerDelegateを以下のように実装してください。

```swift
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return SAInboxAnimatedTransitioningController.sharedInstance.setOperation(operation)
}
```

3: [SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxViewController.swift)はUITableViewを持っているので、そちらを使用して一覧の要素を設定していきます。

4: tableViewのcellが選択された際に遷移するようにするために、下記のようにdelegateメソッドを実装します。

```swift
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: false)
        
    let viewController = DetailViewController()        
    if let cell = tableView.cellForRowAtIndexPath(indexPath), cells = tableView.visibleCells() as? [UITableViewCell] {
        SAInboxAnimatedTransitioningController.sharedInstance.configureCotainerView(self, cell: cell, cells: cells, headerImage: headerView.screenshotImage())
    }
       
    navigationController?.pushViewController(viewController, animated: true)
}
```

遷移をするviewを設定する際に、選択されたcellと画面に表示されているcellと[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxViewController.swift)と[SAInboxDetailViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxDetailViewController.swift)はHeaderViewを持っているのでHeaderViewのスクリーンショットを渡します。

これらの実装でInbox by Googleの遷移を実現することができます。あとは通常のViewControllerを使うようにレイアウトを実装してくことになります。

# カスタマイズ
HeaderViewの表示を一括、またはViewControllerごとにカスタマイズすることができます。

## 一括設定
[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxViewController.swift)のクラスはappearanceのstaticインスタンスを持っているので、下記のような実装が可能です。

```swift
SAInboxViewController.appearance.barTintColor = .blackColor()
SAInboxViewController.appearance.tintColor = .whiteColor()
SAInboxViewController.appearance.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]
```

## ViewControllerごとの設定
[SAInboxViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxViewController.swift)と[SAInboxDetailViewController](https://github.com/szk-atmosphere/SAInboxViewController/blob/master/SAInboxViewController/SAInboxDetailViewController.swift)はappearanceのpropertyを持っているので、下記のような実装が可能です。

```swift
appearance.barTintColor = .whiteColor()
appearance.tintColor = .blackColor()
appearance.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.blackColor()]

enabledViewControllerBasedAppearance = true
```

ViewControllerごとの設定を有効にするViewControllerに対して、`enabledViewControllerBasedAppearance = true`にすることを忘れないでください。

# 最後に
このようにして、容易にInbox by Googleの遷移を実現することができます。
ルートのViewControllerと2つ目のViewControllerを行き来するようなアプリにはむいている遷移だと思います。