0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Swift 5 で画面遷移時にフルスクリーンモードのモーダルのタッチアクションに処理を渡す

Posted at

はじめに

普段は Laravel や Nuxt を使って Web アプリケーションを開発しているのですが、年に数回 iOS アプリに改修が入ることがあります。
Swift を触っていない期間が空いていて、これどうするんだっけ?という事が多いので、メモ代わりに投稿します。

概要

リーダー画面(ReaderPage)でQRコードを読み込んだら、同意画面(AgreementPage)をモーダルのフルスクリーンモードで表示し、同意ボタンを押下すると、モーダルを閉じて「同意済み」と表示する機能を実装します。

同意ボタンを押下すると dismiss() でモーダルを閉じるため、その前に同意済みフラグを立てる方法を2つ紹介します。
また、本アプリケーションでは画面遷移に performSegue() を使用しています。

環境

  • Apple M1 Max
  • macOS Monterey (v12.6)
  • Xcode 13.2.1
  • Swift 5
  • iPadOS 16.3.1

コールバック関数を渡して実行する

一つ目はコールバック関数を渡して実行する方法を紹介します。

まずは AgreementPageViewController にコールバックを格納する変数を定義して、設定されていれば実行されるようにします。

AgreementPageViewController.swift
class AgreementPageViewController: UIViewController {
    public var agreeCallback: (() -> Void)?

    private func agree() {
        self.agreeCallback?()
        
        self.dismiss(animated: true)
    }
}

画面遷移する前に prepare という関数が発火されるのですが、この関数の引数の segue.destinationAgreementPageViewController が格納されています。
この AgreementPageViewController にコールバック関数を設定することで実現できます。

ReaderPageViewController.swift
class ReaderPageViewController: UIViewController {
    private var isAgreed: Bool = false

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        if segue.identifier == "AgreementPage" {
            let vc = segue.destination as! AgreementPageViewController
            vc.agreeCallback = {
                self.isAgreed = true
            })
        }
    }
}

Delegate を設定して実行する

二つ目はデリゲートを設定して実行する方法を紹介します。

まずは、コールバック関数と同じように AgreementPageViewController にデリゲートを格納する変数を定義して、設定されていれば実行されるようにします。
さらに protocol で専用のデリゲートを定義します。

AgreementPageViewController.swift
class AgreementPageViewController: UIViewController {
    private var delegate: AgreementPageViewControllerDelegate?

    private func agree() {
        self.delegate?.agree()
        
        self.dismiss(animated: true)
    }

    public func setAgreementPageViewControllerDelegate(_ delegate: AgreementPageViewControllerDelegate) {
        self.delegate = delegate
    }
}

protocol AgreementPageViewControllerDelegate: NSObjectProtocol {
    func agree()
}

ReaderPageViewController に上記で定義したデリゲートを継承して、関数に処理を書きます。
そして prepare 関数内で AgreementPageViewControllerdelegate に、 ReaderPageViewController を設定することで、同意ボタン押下時に任意の処理を実行することができるようになります。

ReaderPageViewController.swift
class ReaderPageViewController: UIViewController {
    private var isAgreed: Bool = false

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        if segue.identifier == "AgreementPage" {
            let vc = segue.destination as! AgreementPageViewController
            vc.setAgreementPageViewControllerDelegate(self)
        }
    }
}

extension ReaderPageViewController: AgreementPageViewControllerDelegate {
    func agree() {
        self.isAgreed = true
    }
}

おわりに

画面遷移や画面を跨いだデータのやり取りで Delegate ってどう使うんだっけ?となったので、記事にまとめました!
まだデリゲートパターンを理解して切れていないところがあるので、間違った使い方をしていた場合は、ご指摘頂けると助かります!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?