iOS13のautomaticモーダルからfullScreenに横遷移する


![](https://i.imgur.com/C0oMcUd.gif)

こーゆう遷移をする方法を紹介します。

## 前置き

macOS 10.15.x
Xcode 11.2.x
iOS 13.x

画面遷移について、iOS13から通常のモーダル表示（下から表示）が、
ちょっと立体的な `.automatic` 表示になりました。

.automatic | .fullScreen
--- | ---
<img width=320px src="https://i.imgur.com/UKtx5GU.png"> | <img width=320px src="https://i.imgur.com/ngstYur.png">

iOS12以前は通常が.fullScreenでしたね。
.fullScreenで表示したい場合は、
ちゃんと指定するようにしなければならなくなりました。

```swift
let viewController = xxx
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.modalPresentationStyle = .fullScreen
present(navigationController, animated: true, completion: nil)
```

この記事は.automaticの状態から、.fullScreenの状態に、
`pushViewController` 遷移のように横表示する方法を記載します。

## 方法1(?): pushViewController遷移

-> **現状わかりませんでした**

色々調べましたが、同じnavigationControllerで、
modalPresentationStyleを変更する方法は現状見つけられませんでした。

もし方法が存在し、やり方を知っている方がいましたら教えてくださいm(_ _)m

## 方法2: present遷移の横バージョン

`present(viewController, animated: true, completion: nil)`
の遷移って下からですよね。

コレを横から遷移に変更する方法が、方法2です。

**横から遷移サンプルコード:**

```swift
import UIKit

final class TestFirstViewController: UIViewController {

    @IBAction private func clickButton(_ sender: Any) {
        let storyBoard = UIStoryboard(name: "TestSecond", bundle: nil)
        let viewController = storyBoard.instantiateViewController(withIdentifier: "TestSecondViewController")
        let navigationController = UINavigationController(rootViewController: viewController)
        navigationController.modalPresentationStyle = .fullScreen
        let transition = CATransition()
        transition.duration = 0.4
        transition.type = .push
        transition.subtype = .fromRight
        view.window!.layer.add(transition, forKey: kCATransition)
        present(navigationController, animated: false, completion: nil)
    }

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

ポイントは、

- CATransitionを利用して、presentのanimationを定義していること
- presentのanimatedはfalseにすること

です。ちなみに `transition.type` と `transition.subtype` を
変更すれば、他にも様々な画面遷移アニメーションを実現できます。

また、せっかく.automatic状態から横表示を実現しても、
何も設定していなければ、画面を閉じるアニメーションは下方向になってしまいます。
画面を閉じる動作も、横に設定してあげましょう。

**横へ画面閉じるサンプルコード:**

```swift
import UIKit

final class TestSecondViewController: UIViewController {

    @objc private func clickBackBarButtonItem() {
        let transition = CATransition()
        transition.duration = 0.4
        transition.type = .push
        transition.subtype = .fromLeft
        view.window!.layer.add(transition, forKey: kCATransition)
        dismiss(animated: false, completion: nil)
    }

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

    private func setupViews() {
        let backBarButtonItem = UIBarButtonItem(title: "戻る", style: .plain, target: self, action: #selector(clickBackBarButtonItem))
        navigationItem.setLeftBarButton(backBarButtonItem, animated: true)
    }
}

```

表示時と同じく、dismissのanimatedがfalseなことに注意しましょう。

## ちなみに

![](https://i.imgur.com/dh6tWvB.gif)

safariViewControllerを用いた場合は、特に何も指定なく横遷移にできるようです。

```swift
let safariViewController = SFSafariViewController(url: URL(string: "https://google.com")!)
present(safariViewController, animated: true, completion: nil)
```

## まとめ

本当は方法1の方で実現できれば楽なのですが。
今後のアップデートに期待です。

## 参考

https://swallow-incubate.com/archives/blog/20200226/
https://zonneveld.dev/ios-13-viewcontroller-presentation-style-modalpresentationstyle/