(해당 글은 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/
간단한 예제로 살펴보는 iOS Design/Architecture Pattern: Coordinator - Basic
Coordinator Design/Architecture Pattern with UIKit - Basic
lena-chamna.netlify.app
2. SceneDelegate에 코디네이터 적용:
https://markstruzinski.com/2019/08/using-coordinator-with-scene-delegates/
MS | Using Coordinator With Scene Delegates
I have switched to using the coordinator pattern with any new work I do. I was resistant to break away from Storyboards using segues at first. But over the years I’ve learned any app of medium to large complexity breaks down under the weight of segues af
markstruzinski.com
'아직정리안한것들모음집' 카테고리의 다른 글
[Coordinator] 내용 정리 2 (0) | 2023.07.13 |
---|