Swiftで画面遷移をしよう!完全マスターのための10選

Swiftでの画面遷移をイラストで表した画像Swift
この記事は約29分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

あなたがiOSアプリケーションを開発する上で避けて通れないのが「画面遷移」です。

この記事を読めばSwiftでの画面遷移をマスターすることができるようになります。

画面間の移動、データの受け渡し、遷移アニメーションのカスタマイズなど、Swiftでの画面遷移に関する知識を総括的に学べる内容となっています。

●Swiftでの画面遷移の基本

画面遷移とは、一つの画面から別の画面への移動を指します。iOSアプリケーションではこの遷移が頻繁に行われます。

例えば、アイテムのリストから詳細画面への移動、設定画面への移動などがこれに当たります。

○画面遷移のメカニズム

Swiftにおける画面遷移は、主にUIViewControllerというクラスを基に行われます。

UIViewControllerは、iOSアプリケーションの画面一つ一つを管理する役割を持ちます。

画面遷移は、これらのUIViewControllerのインスタンス間で行われるのです。

○UIViewControllerとは

UIViewControllerは、iOSアプリケーションの画面(ビュー)とその画面の振る舞い(コントローラー)を管理するクラスです。

このクラスを継承することで、新しい画面を作成することができます。

例として、新しいUIViewControllerのサブクラスを作成するコードを紹介します。

この例では、SampleViewControllerという新しい画面を作成しています。

import UIKit

class SampleViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 画面が読み込まれた時の処理をこちらに記述します。
    }
}

このコードではSampleViewControllerという名前で新しい画面を作成しています。

viewDidLoad()メソッド内に、画面が読み込まれた際の処理を記述することができます。

○Segueの役割

Segue(セグエ)は、Storyboard上で二つのUIViewController間の遷移を定義するものです。

Segueを使用することで、画面間の移動やデータの受け渡しなど、画面遷移に関する多くの作業を簡単に実現することができます。

Segueを使用して画面遷移を行う基本的な手順は次のようになります。

  1. Storyboard上で、遷移元の画面から遷移先の画面へドラッグを行い、Segueを作成する。
  2. Segueに適切な識別子を付ける。
  3. 必要に応じて、プログラム上で遷移前の処理やデータの受け渡しを実装する。

Segueを使用して画面遷移を行う簡単なサンプルコードを紹介します。

この例では、ボタンをタップした際に新しい画面に遷移するシンプルな機能を実装しています。

import UIKit

class FirstViewController: UIViewController {
    // 画面遷移を実行する関数
    @IBAction func moveToSecondScreen(_ sender: UIButton) {
        performSegue(withIdentifier: "toSecondScreen", sender: nil)
    }

    // Segueを使用して遷移先の画面にデータを渡す
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toSecondScreen" {
            let secondVC = segue.destination as! SecondViewController
            secondVC.data = "Hello from First Screen!"
        }
    }
}

このコードではmoveToSecondScreenメソッドがボタンのアクションとして設定され、ボタンがタップされるとperformSegueメソッドが呼ばれて画面遷移が実行されます。

また、prepareメソッドを使用して遷移先の画面にデータを渡しています。

このコードを実行すると、ボタンをタップした時に”Hello from First Screen!”というメッセージを持ってSecondViewControllerに遷移することができます。

●Swiftでの画面遷移の使い方

Swiftでの画面遷移は、ユーザーエクスペリエンスを向上させる上で非常に重要な要素となります。

ここでは、Swiftを使った基本的な画面遷移の方法を具体的なサンプルコードとともに解説します。

○サンプルコード1:基本的な画面遷移

このコードではpresentメソッドを使って、新しい画面をモーダル表示するコードを紹介しています。

この例では、ボタンをタップすると新しい画面が表示されるシンプルな遷移を実現しています。

import UIKit

class FirstViewController: UIViewController {

    @IBAction func showSecondScreen(_ sender: UIButton) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let secondVC = storyboard.instantiateViewController(identifier: "SecondViewController") as! SecondViewController
        present(secondVC, animated: true, completion: nil)
    }
}

上記のコードを実行すると、FirstViewControllerに配置したボタンをタップするとSecondViewControllerがモーダル表示されます。

○サンプルコード2:ボタンを使った画面遷移

画面遷移のトリガーとして最も一般的なのはボタンのタップです。

このコードではperformSegueメソッドを使って、特定のSegueを実行して画面遷移を行うコードを紹介しています。

この例では、Storyboard上で定義したSegueをプログラムから呼び出して、画面遷移を行っています。

import UIKit

class ThirdViewController: UIViewController {

    @IBAction func moveToFourthScreen(_ sender: UIButton) {
        performSegue(withIdentifier: "toFourthScreen", sender: nil)
    }
}

上記のコードを使うと、ThirdViewControllerに配置したボタンをタップすることで、Storyboard上で”toFourthScreen”という識別子を持つSegueが実行され、指定した画面へ遷移します。

●Swiftでの画面遷移の使い方

前章では、Swiftでの基本的な画面遷移の方法について解説しました。

ここでは、より実践的な画面遷移の方法や、遷移時にデータを渡す方法などに焦点を当てて解説します。

○サンプルコード3:値を渡して画面遷移

多くの場合、画面遷移を行う際に一つの画面から別の画面へデータを渡す必要があります。

このコードではprepare(for:sender:)メソッドを使用して、遷移先のViewControllerにデータを渡す方法を紹介しています。

この例では、FirstViewControllerからSecondViewControllerへ文字列のデータを渡す遷移を実現しています。

import UIKit

class FirstViewController: UIViewController {
    var dataToSend: String = "Hello from FirstViewController!"

    @IBAction func goToSecondViewController(_ sender: UIButton) {
        performSegue(withIdentifier: "toSecondViewController", sender: nil)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toSecondViewController" {
            let destinationVC = segue.destination as! SecondViewController
            destinationVC.receivedData = dataToSend
        }
    }
}

class SecondViewController: UIViewController {
    var receivedData: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let data = receivedData {
            print(data) // "Hello from FirstViewController!"
        }
    }
}

上記のコードを使用することで、FirstViewControllerからSecondViewControllerへデータを渡す遷移を行うことができます。

具体的には、SecondViewControllerviewDidLoadメソッド内で渡されたデータを受け取っています。

○サンプルコード4:Storyboardから画面遷移

Storyboardを活用することで、グラフィカルに画面遷移を設定することができます。

このコードでは、Storyboard上で設定したSegueを利用して画面遷移を行う方法を紹介しています。

この例では、ボタンのアクションを直接Storyboard上で設定して画面遷移を行います。

// ViewController.swift

import UIKit

class ThirdViewController: UIViewController {
    // コード内での画面遷移の設定は不要。全てStoryboard上で行う。
}

上記のコードでは、ThirdViewControllerに特別なコードを記述することなく、Storyboard上で直接Segueを設定することで画面遷移を行っています。

具体的には、ボタンの「touch up inside」イベントをSegueにリンクさせることで、ボタンをタップすると指定した遷移が実行されるようになります。

○サンプルコード5:プログラム上からの画面遷移

Storyboardを使わずに、プログラムのみで画面遷移を行う方法もあります。

特定の条件下での遷移や、複雑な遷移を実装したい場合などに役立ちます。

このコードでは、UIStoryboardのインスタンスを使って、プログラム上から画面遷移を行う方法を紹介しています。

この例では、MainViewControllerからDetailViewControllerへの遷移を実現しています。

import UIKit

class MainViewController: UIViewController {

    @IBAction func goToDetailViewController(_ sender: UIButton) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let detailViewController = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
        self.navigationController?.pushViewController(detailViewController, animated: true)
    }
}

class DetailViewController: UIViewController {
    // 遷移先での処理をここに記述
}

上記のコードを使用することで、ボタンアクションをトリガーとして、MainViewControllerからDetailViewControllerへの遷移を行うことができます。

具体的には、UIStoryboardinstantiateViewControllerメソッドを使用して、遷移先のDetailViewControllerをインスタンス化し、pushViewControllerメソッドを用いて遷移を実行しています。

この方法の利点は、コードの中で遷移先のViewControllerを明示的に指定できることです。

これにより、動的な遷移先の変更や、複数の遷移先から選択するなどの柔軟な遷移が可能になります。

逆に、Storyboard上で視覚的に遷移の流れを把握することができないため、遷移の流れが複雑になると管理が難しくなることがあります。

一方、このプログラム上での遷移を実現する際には、DetailViewControllerのStoryboard IDを正確に設定することが必要です。

Storyboard上でDetailViewControllerを選択し、属性インスペクターからStoryboard IDにDetailViewControllerという名前を設定することで、上記のコードでの遷移が可能となります。

●Swiftでの画面遷移の応用例

Swiftを使用して、画面遷移をより高度にカスタマイズするための応用例をいくつか紹介します。

これらの応用例は、標準的な画面遷移を超えて、ユーザーエクスペリエンスを向上させるためのものです。

○サンプルコード6:タブバーコントローラを使用した画面遷移

多くのアプリで見られるタブバーを使った画面遷移は、ユーザーにとって直感的に操作が可能です。

このコードでは、UITabBarControllerを使って、タブでの画面遷移を実現しています。

この例では、3つのタブでそれぞれ異なるViewControllerを表示しています。

import UIKit

class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let firstVC = FirstViewController()
        firstVC.tabBarItem = UITabBarItem(title: "First", image: nil, tag: 0)

        let secondVC = SecondViewController()
        secondVC.tabBarItem = UITabBarItem(title: "Second", image: nil, tag: 1)

        let thirdVC = ThirdViewController()
        thirdVC.tabBarItem = UITabBarItem(title: "Third", image: nil, tag: 2)

        self.viewControllers = [firstVC, secondVC, thirdVC]
    }
}

このコードを用いることで、3つの異なるViewControllerをタブバーで切り替えることができます。

各ViewControllerにはタブのタイトルや画像を設定することが可能で、これによってユーザーは簡単に異なる機能や情報にアクセスできます。

○サンプルコード7:ページビューコントローラを使用した画面遷移

チュートリアルや一連の画像を表示する際に、ページビューコントローラが役立ちます。

このコードでは、UIPageViewControllerを用いて複数のViewControllerをページング形式で表示しています。

import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDataSource {

    var viewControllersList: [UIViewController] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        let firstVC = FirstViewController()
        let secondVC = SecondViewController()

        viewControllersList.append(firstVC)
        viewControllersList.append(secondVC)

        self.dataSource = self
        self.setViewControllers([viewControllersList[0]], direction: .forward, animated: true, completion: nil)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let index = viewControllersList.firstIndex(of: viewController), index > 0 else { return nil }
        return viewControllersList[index - 1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let index = viewControllersList.firstIndex(of: viewController), index < viewControllersList.count - 1 else { return nil }
        return viewControllersList[index + 1]
    }
}

上記のコードにより、ユーザーはスワイプ操作でFirstViewControllerSecondViewControllerを切り替えることができます。

ページビューコントローラは、コンテンツの順番を容易に制御したり、ページ間でのスムーズな遷移を実現するためのものです。

○サンプルコード8:モーダル遷移のカスタマイズ

モーダル遷移は、新しい画面が現在の画面の上に重ねて表示される遷移方法です。

Swiftでは、モーダル遷移のアニメーションや表示スタイルを簡単にカスタマイズすることができます。

このコードでは、モーダル遷移のアニメーションや表示方法をカスタマイズする方法を表しています。

この例では、モーダルをフルスクリーンで表示し、アニメーションをカスタマイズしています。

import UIKit

class MainViewController: UIViewController {

    @IBAction func showModalButtonTapped(_ sender: UIButton) {
        let modalVC = ModalViewController()

        // モーダルの表示スタイルを設定
        modalVC.modalPresentationStyle = .fullScreen

        // カスタムアニメーションを設定
        modalVC.modalTransitionStyle = .crossDissolve

        present(modalVC, animated: true, completion: nil)
    }
}

モーダルの表示スタイルは、modalPresentationStyleプロパティを使用して設定します。

また、遷移のアニメーションスタイルは、modalTransitionStyleプロパティで設定できます。

この例では、crossDissolveを使用して、クロスフェードのアニメーションでモーダルが表示されるようにしています。

○サンプルコード9:アニメーションを伴う画面遷移

アプリのUIを魅力的にするためには、画面遷移にアニメーションを追加することが一つの方法となります。

下記のコードでは、カスタムアニメーションを使って画面間を遷移しています。

import UIKit

class AnimatedTransitionViewController: UIViewController, UIViewControllerTransitioningDelegate {

    @IBAction func showAnimatedTransitionButtonTapped(_ sender: UIButton) {
        let nextVC = NextViewController()
        nextVC.transitioningDelegate = self
        nextVC.modalPresentationStyle = .custom

        present(nextVC, animated: true, completion: nil)
    }

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomAnimationPresenter()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomAnimationDismisser()
    }
}

class CustomAnimationPresenter: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // ここでカスタムアニメーションを実装
    }
}

class CustomAnimationDismisser: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // ここでカスタムアニメーションを実装
    }
}

このコードを用いることで、NextViewControllerへの遷移時と、そのViewControllerを閉じる際に、カスタムアニメーションを使用して画面遷移が行われます。

具体的なアニメーションの実装は、CustomAnimationPresenterクラスとCustomAnimationDismisserクラス内のanimateTransitionメソッド内で行います。

○サンプルコード10:画面遷移の逆方向制御

Swiftでは、画面遷移の方向を逆にすることも容易にできます。

これは、例えばユーザーのアクションに応じて遷移方向を変えたりする場合に便利です。

下記のコードでは、条件に応じて遷移の方向を変更する方法を表しています。

import UIKit

class DirectionViewController: UIViewController {

    var shouldReverseTransition = false

    @IBAction func showDirectionButtonTapped(_ sender: UIButton) {
        let nextVC = NextDirectionViewController()

        if shouldReverseTransition {
            let transition = CATransition()
            transition.duration = 0.5
            transition.type = CATransitionType.push
            transition.subtype = CATransitionSubtype.fromLeft

            view.window!.layer.add(transition, forKey: kCATransition)
        }

        present(nextVC, animated: true, completion: nil)
    }
}

shouldReverseTransition変数がtrueの場合、画面遷移の方向が左から右となります。

このように条件分岐を使って、画面遷移のアニメーションや方向をカスタマイズすることができます。

●画面遷移時の注意点と対処法

Swiftでの画面遷移は簡単に実装できる反面、注意しなければならないポイントもいくつか存在します。

ここでは、画面遷移時の代表的な注意点とその対処法を詳しく解説します。

○循環参照の回避

循環参照とは、2つのオブジェクトが互いに参照し合い、メモリの解放が行われない状態を指します。

これが発生すると、メモリリークを引き起こす可能性があります。

特に、クロージャ内でselfを強参照すると、この問題が生じやすくなります。

このコードでは、ViewControllerから別のViewControllerに遷移する際に循環参照を回避する方法を表しています。

この例では、クロージャ内で[weak self]を使用して、弱参照にして循環参照を避けています。

import UIKit

class FirstViewController: UIViewController {

    var completion: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()

        completion = { [weak self] in
            self?.performSegue(withIdentifier: "toSecondVC", sender: nil)
        }
    }

    @IBAction func moveToNextPage(_ sender: UIButton) {
        completion?()
    }
}

○画面遷移時のデータの同期問題

画面遷移を行う際、データの同期が取れていない場合、ユーザーに不正確な情報が表示されるリスクがあります。

特に、非同期処理を伴う場合に注意が必要です。

下記のコードでは、非同期処理を伴うデータの取得と、そのデータを別の画面に渡す方法を表しています。

この例では、DispatchQueueを用いて非同期処理を行い、遷移先のViewControllerにデータを渡しています。

import UIKit

class DataViewController: UIViewController {

    var data: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        // 非同期処理でデータを取得
        DispatchQueue.global().async {
            // データ取得処理(ダミーとして固定の文字列を設定)
            let fetchedData = "非同期で取得したデータ"

            DispatchQueue.main.async {
                self.data = fetchedData
            }
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toNextVC", let nextVC = segue.destination as? NextViewController {
            nextVC.receivedData = data
        }
    }
}

class NextViewController: UIViewController {

    var receivedData: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        print(receivedData ?? "データなし")
    }
}

このように、非同期処理を行う際は、データの同期を意識しながらコーディングを行うことで、画面遷移時の不具合やユーザーへの混乱を防ぐことができます。

●カスタマイズの方法

Swiftでの画面遷移は、基本的な方法だけでなく、様々なカスタマイズを行うことで、よりユニークで魅力的なユーザー体験を提供することができます。

ここでは、画面遷移のアニメーションのカスタマイズや、遷移先の画面デザインの変更方法について詳しく解説します。

○画面遷移アニメーションのカスタマイズ

画面遷移の際のアニメーションは、デフォルトで設定されていますが、これをカスタマイズすることで、アプリのブランドイメージやテーマに合わせた遷移を実現することができます。

このコードでは、カスタムアニメーションを使って画面遷移を行う方法を紹介しています。

この例では、画面がフェードインしながら遷移するアニメーションを実装しています。

import UIKit

class CustomAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromView = transitionContext.view(forKey: .from),
              let toView = transitionContext.view(forKey: .to) else { return }

        let duration = transitionDuration(using: transitionContext)

        transitionContext.containerView.addSubview(toView)
        toView.alpha = 0

        UIView.animate(withDuration: duration, animations: {
            toView.alpha = 1.0
        }) { _ in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

このカスタムアニメーションを適用するには、次のようにUINavigationControllerDelegateを利用します。

import UIKit

class CustomNavigationController: UINavigationController, UINavigationControllerDelegate {

    let customAnimationController = CustomAnimationController()

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return customAnimationController
    }
}

○遷移先の画面デザイン変更

遷移先の画面デザインを変更することで、異なるコンテンツや機能に合わせてユーザーに最適な画面を提供することができます。

例として、遷移先の背景色やタイトルを動的に変更する方法を紹介します。

このコードでは、遷移先のViewControllerで背景色を変更し、タイトルを設定する方法を表しています。

この例では、遷移先のViewControllerで背景色を青に設定し、タイトルを「詳細画面」として表示しています。

import UIKit

class DetailViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // 背景色を青に設定
        view.backgroundColor = .blue

        // タイトルを設定
        title = "詳細画面"
    }
}

まとめ

Swiftを使用しての画面遷移は、非常に幅広いカスタマイズが可能です。

基本的な画面遷移から、アニメーションを伴う画面遷移、さらには高度なカスタマイズまで、多岐にわたる方法を学ぶことができたかと思います。

この知識を活かすことで、ユーザーエクスペリエンスを向上させることが期待されます。

また、注意点として、循環参照を回避することや、画面遷移時のデータ同期の問題への対応も大切です。

これらを意識しつつ、Swiftでの画面遷移の実装を進めることで、バグの少ない、使いやすいアプリケーションを作成することができます。

初心者から中級者まで、この記事を通じて画面遷移に関する知識を深めることができたことを願っています。

今後のアプリ開発に、この記事で学んだ知識をぜひ活用してください。