Skip to content

Instantly share code, notes, and snippets.

@HaruhikoMotokawa
Last active September 26, 2023 07:37
Show Gist options
  • Save HaruhikoMotokawa/39fb5958d7325af63c7542c333618582 to your computer and use it in GitHub Desktop.
Save HaruhikoMotokawa/39fb5958d7325af63c7542c333618582 to your computer and use it in GitHub Desktop.
import UIKit
/// このプロトコルで画面遷移のインターフェースを共通化
protocol Coordinator {
func start()
}
/// 初期起動経路を管理するクラス
final class AppCoordinator: Coordinator {
// プロパティとしてUIWindowとUINavigationControllerを保持する
private let window: UIWindow
private let rootViewController: UINavigationController
// AppCoordinatorに最初の画面のCoordinatorを紐づけて親子関係にする
// 子がFirstCoordinator
private var firstCoordinator: FirstCoordinator
// windowとUINavigationControllerを初期化
init(window: UIWindow) {
self.window = window
rootViewController = .init()
// 初期化時にFirstCoordinatorのインスタンスを保持、この時に
// UINavigationControllerをrootとして渡す
firstCoordinator = FirstCoordinator(navigator: rootViewController)
}
func start() {
// firstCoordinatorを起動(つまりFirstVCに画面遷移)
firstCoordinator.start()
// 保持していたUINavigationControllerをwindowのrootに設定してアクティブにする
window.rootViewController = rootViewController
window.makeKeyAndVisible()
}
}
import UIKit
// ①Coordinatorプロトコルを継承
// VCのインスタンスを保持して、画面遷移を担当する
final class FirstCoordinator: Coordinator {
private let navigator: UINavigationController
private var firstViewController: FirstViewController?
private var secondCoordinator: SecondCoordinator?
private var redCoordinator: RedCoordinator?
// ②今回は初期化時にUINavigationControllerを代入
init(navigator: UINavigationController) {
self.navigator = navigator
}
// ③vcを初期化し、自身のプロパティとして保持する
func start() {
let vc = FirstViewController()
vc.delegate = self
// FirstViewControllerが最初の画面であると設定(リセット)
self.navigator.viewControllers = [vc]
self.firstViewController = vc
}
}
// SecondViewControllerに画面遷移するためにSecondCoordinatorを起動する
extension FirstCoordinator: FirstViewControllerDelegate {
func navigateToNextPage() {
// SecondCoordinatorを初期化する際に保持していたUINavigationControllerを渡す
let secondCoordinator = SecondCoordinator(navigator: self.navigator)
// secondCoordinatorを起動、つまり画面遷移処理の実行
secondCoordinator.start()
// 画面遷移後にSecondCoordinatorを保持しておく
self.secondCoordinator = secondCoordinator
}
func showRedView() {
let redCoordinator = RedCoordinator(navigator: self.navigator)
redCoordinator.start()
self.redCoordinator = redCoordinator
}
}
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
/// 画面の起動経路を管理するためにAppCoordinatorクラスを参照する
private var appCoordinator: AppCoordinator?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// widowを作成して保持
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
// 作成したwindowをAppCoordinatorのインスタンスに渡す
// ここでは設定項目や状態を渡してるだけで、まだ起動はしていない
let appCoordinator = AppCoordinator(window: window)
// 画面を起動
appCoordinator.start()
// appCoordinatorを保持
self.appCoordinator = appCoordinator
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment