(해당 글은 https://lena-chamna.netlify.app/post/ios_design_pattern_coordinator_basic/ 를 참고해 작성한 글입니다.)
Coordinator란?
코디네이터는 하나 이상의 뷰 컨트롤러에게 지시를 내리는 객체이다.
여기서 말하는 지시는 화면 전환에 대한 지시를 의미한다.
코디네이터 패턴에서는 현재 ViewController에서 그 다음 ViewController로 이동할 때 직접 push나 present등의 화면 전환을 하지 않는다.
그 대신 모든 화면 네비게이션을 코디네이터가 관리한다.
즉, ViewController에서 Navigation의 책임을 다른 클래스로 분리한다.
따라서 ViewController들 간에 의존성이 낮아지게 된다.
Coordinator 특징
1. 코디네이터 별로 하나 또는 그 이상의 ViewController를 보유한다.
2. 각 코디네이터는 일반적으로 "start"로 불리는 메서드를 사용하여 ViewController를 표시한다.
3. 각 ViewController에는 코디네이터에 대한 delegate reference가 있다.
4. 각 코디네이터는 child 코디네이터 배열을 가지고 있다.
5. 각 child 코디네이터는 parent 코디네이터에 대한 delegate reference가 있다.
간단한 코디네이터 예제
참고 블로그에서는 SceneDelegate를 삭제하고 AppDelegate에서 코디네이터를 적용했지만, 나는 SceneDelegate를 지우지 않고 진행해보도록 하겠다.
1단계:
1. Coordinator 프로토콜 생성
import UIKit
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
2. MainCoordinator 클래스 생성
메인 코디네이터는 구조에서 확인 가능하듯이 가장 최상위에 위치한 코디네이터 객체이다.
class MainCoordinator: NSObject, Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let vc = ViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: false)
}
// 나머지 구현부 생략
}
2단계:
SceneDelegate에서 메인 코디네이터 객체 생성하기
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var appCoordinator: MainCoordinator!
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// 1
guard let windowScene = (scene as? UIWindowScene) else {
return
}
// 2
let appWindow = UIWindow(frame: windowScene.coordinateSpace.bounds)
appWindow.windowScene = windowScene
// 3
let navController = UINavigationController()
appCoordinator = AppCoordinator(navigationController: navController)
appCoordinator.start()
// 4
appWindow.rootViewController = navController
appWindow.makeKeyAndVisible()
// 5
window = appWindow
}
func sceneDidDisconnect(_ scene: UIScene) {
}
func sceneDidBecomeActive(_ scene: UIScene) {
}
func sceneWillResignActive(_ scene: UIScene) {
}
func sceneWillEnterForeground(_ scene: UIScene) {
}
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as? AppDelegate)?.saveContext()
}
}
3단계:
첫 화면에서 다음 화면들로 이동하기
첫 화면에 두개의 버튼이 있다고 가정하고, 각 버튼을 누르면 다른 화면이 나타나도록 하겠다.
MainCoordinator.swift
class MainCoordinator: NSObject, Coordinator {
// 나머지 구현부 생략
func buySubscription() {
let vc = BuyViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: true)
}
func createAccount() {
let vc = CreateAccountViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: true)
}
}
ViewController.swift
class ViewController: UIViewController, Storyboarded {
weak var coordinator: MainCoordinator?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buyTapped(_ sender: Any) {
// coordinator를 통해 화면 전환
self.coordinator?.buySubscription()
}
@IBAction func createAccount(_ sender: Any) {
// coordinator를 통해 화면 전환
self.coordinator?.createAccount()
}
}
참고링크:
1. 코디네이터 설명:
https://lena-chamna.netlify.app/post/ios_design_pattern_coordinator_basic/
2. SceneDelegate에 코디네이터 적용:
https://markstruzinski.com/2019/08/using-coordinator-with-scene-delegates/
'아직정리안한것들모음집' 카테고리의 다른 글
[Coordinator] 내용 정리 2 (0) | 2023.07.13 |
---|