์๋ ํ์ธ์ ์ ์ธ์ ๋๋ค!
์ค๋์ ์ฐธ์ฌํ๊ณ ์๋ ํ๋ก์ ํธ์ ๋์ ํ๊ฒ ๋ ์ฝ๋๋ค์ดํฐ ํจํด์ ๋ํด ์ ๋ฆฌํด๋ณด๋ คํฉ๋๋ค.
์ฝ๋๋ค์ดํฐ๋ฅผ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๋ ๊ฒ์ด ์ฒ์์ด๋ผ ๊ณต๋ถ๋ฅผ ํ๋ฉด์ ์ ์ฉํ๋ ๊ณผ์ ์ ์๊ธฐ ๋๋ฌธ์
์ด๋ฒ ํฌ์คํ ์์๋ ์ฝ๋๋ค์ดํฐ ํจํด์ด ๋ฌด์์ธ์ง ์์๋ณด๋ ์ ๋๋ก๋ง ์ ๋ฆฌํ๊ณ , ๋ค๋ฅธ ํฌ์คํ ์ผ๋ก ๊ตฌ์ฒด์ ์ธ ์ ์ฉ๊ธฐ๋ฅผ ๋ค๊ณ ์ค๋๋ก ํ๊ฒ ์ต๋๋ค!!
์ด ์ ์ฐธ๊ณ ํด์ ์ฝ์ด์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค : )
Coordinator Pattern์ ๋์ ํ๊ฒ ๋ ๊ณ๊ธฐ
MVVM ์ํคํ ์ฒ๋ฅผ ์ ์ฉํด UI์ ๋น์ฆ๋์ค ๋ก์ง ์ฝ๋๋ฅผ ๋ถ๋ฆฌํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ณผ์ ์์ ํ๋ฉด์ ํ์ ์ด๋์ ํด์ค์ผํ๋๊ฑฐ์ง..?
๋ผ๋ ์๋ฌธ์ด ๋ค์์๋๋ฐ์, ํ๋ฉด์ ํ์ด ๋ฐ์ง๊ณ ๋ณด๋ฉด UI์ ๊ด๋ จ๋ ๋ถ๋ถ์ ์๋์ง๋ง ViewController๊ฐ ๋ค์ ํ๋ฉด์ present ํด์ฃผ์ด์ผํ๋๊น..๋ผ๋ ์๊ฐ์ VC์ ํ๋ฉด์ ํ ์ฝ๋๋ฅผ ์์ฑํด์ค ์ ์ด ์์ต๋๋ค.
MVVM ์ํคํ ์ฒ๋ฅผ ๋์ ํ๊ฒ ๋ ์ด์ ๊ฐ ๊ธฐ์กด MVC ํจํด์์ VC๊ฐ ๋ชจ๋ ์ญํ ์ ๋ด๋นํ๊ณ ์์๊ธฐ ๋๋ฌธ์ VC๊ฐ ์ ์ ๋ฌด๊ฑฐ์์ง๊ฒ ๋๋ค๋ ๋จ์ ์ด ์์ด VC์ ์ญํ ์ ๋ถ๋ฆฌํด์ฃผ๊ธฐ ์ํด์์๋๋ฐ์, ํ๋ฉด์ ํ ์ฝ๋๋ VC๊ฐ ๋ด๋นํ๋๊น ๋ญ๊ฐ ์ญํ ๋ถ๋ฆฌ๋ฅผ ๋ํ ๋๋...๊ณผ ํจ๊ป MVVM ํจํด์ ์ ๋๋ก ์ ์ฉํ๊ณ ์๋ ๊ฒ์ด ๋ง๋?? ํ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ํ๋ฉด์ ํ ์ฝ๋๊น์ง ๋ถ๋ฆฌํด์ VC๋ ์ ๋ง UI๋ง ๋ณด์ฌ์ฃผ๋ ์ญํ ๋ง ํ๊ฒ ํ ์ ์์๊น? ํ๋ฉฐ ์ฐพ์๋ณด๋ค Coordinator Pattern์ผ๋ก ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค!
๊ธฐ์กด์ ํ๋ฉด ์ ํ ๋ฐฉ์
iOS์์๋ ํ๋ฉด ์ ํ์ ๋ด๋นํ๋ ์ปจํธ๋กค๋ฌ์ธ UINavigationController๊ฐ ์์ต๋๋ค. Stack ๋ฐฉ์์ผ๋ก ์๋ก์ด ํ๋ฉด์ pushํ๊ณ , ์ด์ ํ๋ฉด์ผ๋ก ๋์๊ฐ๊ฐ๊ธฐ ์ํด popํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ์ฃ ! ๊ฐ์ฅ ์ฒซ ํ๋ฉด์ ๊ธฐ์ค์ผ๋ก ์๋ก์ด ํ๋ฉด์ผ๋ก ๋์ด๊ฐ๋ ๋ง๋ค ์์๋๋ก ์์ด๊ณ , ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ์ ํตํด ์ด์ ์ ๋ฐฉ๋ฌธํ๋ ํ๋ฉด๋ค์ ์์๋๋ก ๊บผ๋ผ ์ ์์ต๋๋ค.
navigationController?.pushviewController(nextViewController, animated:true)
push, pop์ ์ด์ฉํ์ฌ ์ฝ๊ณ ๊ฐ๋จํ๊ฒ ํ๋ฉด์ ์ ํ ํ ์ ์์ง๋ง, ๋จ์ ์ด ์กด์ฌํฉ๋๋ค.
์ฑ์ด ์ ์ฐจ ์ปค์ง๊ณ ํ๋ฉด์ด ๋ง์์ ธ ํ๋ฉด์ ํ ํ๋ก์ฐ๊ฐ ๋ณต์กํด์ง๊ฒ ๋๋ฉด ๋ค๋น๊ฒ์ด์ ์คํ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๊ณ ,
ํ๋ฉด์ ์ ํํ๋ ์ฝ๋๊ฐ ์ฌ์ฉํ๋ ViewController๋ฅผ ์์กดํ๊ธฐ ๋๋ฌธ์ VC๊ฐ ๋ฌด๊ฑฐ์์ง๊ฒ ๋ฉ๋๋ค..
์ด๋ฌํ ๋จ์ ๋ค์ ์ง์ ๋๊ผ๊ธฐ ๋๋ฌธ์ ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ Coordinator ํจํด์ ๋์ ํ๊ฒ ๋ ๊ฒ์ ๋๋ค!
Coordinator Pattern์ด๋?
์ฝ๋๋ค์ดํฐ ํจํด์ ViewController๋ก ๋ถํฐ ํ๋ฉด ์ ํ์ ๋ถ๋ด์ ์ค์ฌ์ฃผ๊ณ , ํ๋ฉด์ ํ์ ๋ณด๋ค ๋ ๊ด๋ฆฌํ๊ธฐ ์ฝ๋๋ก ๋์์ฃผ๊ธฐ ์ํ ํจํด์ ๋๋ค. (ํ๋ฉด์ ํ๋ฆ์ ์ ์ดํด์ฃผ๋ ์ญํ , ๋ผ์ฐํ , VC๊ด๋ฆฌ)
์ฝ๋๋ค์ดํฐ ํจํด์ ์ฌ์ฉํ๋ฉด ์ป์ ์ ์๋ ์ฅ์ ์ ๋ฌด์์ผ๊น์??
coordinator ํจํด์ ์ฌ์ฉํ๋ฉด, ViewController ์ฌ์ด์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถฐ ์ค ์ ์์ต๋๋ค.
ํ๋ฉด์ ํ์ coordinator๊ฐ ๋ชจ๋ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์, ๊ฐ ViewController๋ ์ด์ ์ ์ด๋ค ์ปจํธ๋กค๋ฌ๊ฐ ์์๋์ง, ๋ค์์ ์ด๋ค ์ปจํธ๋กค๋ฌ๊ฐ ์ค๋์ง ์ ํ์๊ฐ ์์ต๋๋ค. ์ค๋ก์ง coordinator๋ง์ด ์ด๊ฒ์ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ VC ์ฌ์ด์ ๊ฒฐํฉ๋๋ ๋ฎ์์ง๊ฒ ์ฃ ??
๋ํ, coordinator๋ฅผ ์ด์ฉํ ํ๋ฉด ์ ํ ์ ViewController์์ ์ฌ์ฉํ ViewModel์ ํจ๊ป ์ฃผ์ ํด์ค ์ ์์ด DI ๋ํ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค! (ViewModel์ VC ๋ด๋ถ๊ฐ ์๋ ์ธ๋ถ์ ์ ์ํ๋๋ก ํ์ฌ ์์กด์ฑ์ ๋ถ๋ฆฌ์ํฌ ์ ์์ต๋๋ค.)
์ฝ๋๋ค์ดํฐ๋ฅผ ์์กด์ฑ ์ฃผ์ ์ ํด์ค ์ ์๋ ํ๋ธ๋ผ๊ณ ์๊ฐํ๋ฉด ์ดํด๊ฐ ์ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
์ ๋ฆฌํ์๋ฉด, ์ฝ๋๋ค์ดํฐ๋ ํ๋ฉด ์ ํ ์ ์ด ๋ด๋น์์ด์ ์์กด์ฑ ์ฃผ์ ์ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ํ๋ธ๋ผ๊ณ ํ ์ ์์ ๊ฒ ๊ฐ๋ค์!!
Coordinator Pattern์ ํ๋ฆ
์ฑ ๊ท๋ชจ๊ฐ ์ปค์ง๋ค๋ฉด, ์์ ๊ฐ์ ํํ๋ก ์ฝ๋๋ค์ดํฐ ํจํด์ ์ ์ฉํ ์ ์์ต๋๋ค!
๋ฌผ๋ก ๊ฐ๋จํ ์ฑ์ ๊ฒฝ์ฐ ์ฝ๋๋ค์ดํฐ ํ๋๋ง ๋๊ณ ๋ ํ๋ฉด์ ํ์ ๊ด๋ฆฌํ ์ ์๊ฒ ์ง๋ง, ๊ธฐ์กด์ UINavigationController๋ฅผ ์ฌ์ฉํด ํ๋ฉด์ ํ์ ํด์คฌ๋ ๊ฒฝํ์ ์๊ฐํด๋ณธ๋ค๋ฉด, ์ฑ์ ๊ท๋ชจ๊ฐ ํด ๊ฒฝ์ฐ ์คํ ํ๋๋ง์ผ๋ก ํ๋ฉด์ ํ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์ดํดํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
๊ธฐ์กด์ ๋ฐฉ์์์ ๋ณดํต ํญ๋ณ๋ก NavigationController๋ฅผ ํ๋์ฉ ๋๊ณ ๊ด๋ฆฌํด์ฃผ์์๋๋ฐ,
coordinator ํจํด๋ ๋น์ทํ๊ฒ ์ต์์์ MainCoordinator๊ฐ ์กด์ฌํ๊ณ ํ์์ ๊ฐ๊ฐ์ ์คํ(๋ณดํต ํญ ๋จ์๋ ์ญํ ๋จ์)์ ๊ด๋ฆฌํ๋ ํ์ ์ฝ๋๋ค์ดํฐ์ธ ChildCoordinator๋ค์ ๋๊ณ ํ๋ฉด์ ํ์ ๊ด๋ฆฌํฉ๋๋ค.
- ์ต์์ Coordinator: ChildCoordinator(ํ์ ์ฝ๋๋ค์ดํฐ)๋ฅผ ์์ฑํ๊ณ ์ ๊ฑฐ. ๋ชจ๋ ์ฝ๋๋ค์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ
- ChildCoordinator: ํ๋ฉด ์ ํ์ ์ํํ๋ ์ญํ
ํ๋ฉด์ ์ ํํด์ผํ ๋, ๊ฐ๊ฐ์ View ๋ด๋น Coordinator์๊ฒ ์์ฒญ์ ๋ณด๋ด๋ฉด ์ด ์์ฒญ์ ๋ฐ์ Coordinator๋ ์๋ต์ผ๋ก ํ๋ฉด์ ์ ํ์์ผ์ฃผ๋ ๋ฐฉ์์ผ๋ก ์๋ํ๋ค๊ณ ํ ์ ์๋๋ฐ์, ๊ฐ๋จํ ์ฝ๋๋ฅผ ๋ณด๋ฉด์ ์ดํดํด๋ด ์๋ค!
์ฝ๋๋ก ์ดํดํด๋ณด์
MainViewController์์ ์ฒซ๋ฒ์งธ ๋ฒํผ์ ๋๋ฅด๋ฉด FirstViewController, ๋๋ฒ์งธ ๋ฒํผ์ ๋๋ฅด๋ฉด SecondViewController๋ก ๋ฒํผ์ ๋ฐ๋ผ ๋ค๋ฅธ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๊ณ , FirstViewController๋ก ์ด๋ํ์ ๊ฒฝ์ฐ์๋ ํ๋ฉด์ ๋ฒํผ ํด๋ฆญ ์ ๋ ๋ค๋ฅธ ๋ทฐ๋ก์ ์ ํ๊น์ง ์ฝ๋๋ค์ดํฐ๋ฅผ ์ด์ฉํด์ ๊ตฌํํด๋ณด๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค! ๊ตฌ์กฐ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด MainCoordinator ๋ฐ์ ๋๊ฐ์ ํ์ ์ฝ๋๋ค์ดํฐ๋ค(FirstCoordinator, SecondCoordinator)์ ๋๋ ํํ๋ก ์ก์๋ณด๊ฒ ์ต๋๋ค!
protocol ์์ฑ
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
๋จผ์ , ํ๋กํ ์ฝ์ ์์ฑํด์ค๋๋ค.
์ด ํ๋กํ ์ฝ์ ์์ Coordinator๋ค์ ๊ฐ์ง๊ณ ์์ ๋ฐฐ์ด๊ณผ navigation ์คํ์ ์์ UINavigationController ํ์ ์ ๋ณ์(ํ๋ฉด์ ํ์ ๊ธฐ์ค์ด ๋๋ ๋ค๋น๊ฒ์ด์ ์ปจํธ๋กค๋ฌ๋ฅผ ์์ ํ๊ธฐ ์ํ ๋ณ์), ๊ทธ๋ฆฌ๊ณ ์์ ์ ์คํ๋ ํจ์(์ฒซ ํ๋ฉด์ ๋์์ฃผ๋ ๋ฉ์๋)๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
MainCoordinator ์ ์
์์์ ์ ์ํ ํ๋กํ ์ฝ์ ์ฑํํ๋ MainCoordinator ํด๋์ค๋ฅผ ์์ฑํฉ๋๋ค.
class MainCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let mainViewController = MainViewController()
mainViewController.coordinator = self
navigationController.pushViewController(mainViewController, animated: true) // ํ๋ฉด์ ํ
}
func pushFirstViewController() {
let firstCoordinator = FirstCoordinator(navigationController: navigationController)
firstCoordinator.parentCoordinator = self
childCoordinators.append(firstCoordinator)
firstCoordinator.start()
}
func pushSecondViewController() {
let secondCoordinator = SecondCoordinator(navigationController: navigationController)
secondCoordinator.parentCoordinator = self
childCoordinators.append(secondCoordinator)
secondCoordinator.start()
}
}
init ์์ฑ์์ ์ธ์๋ก navigationController๋ฅผ ๋ฃ์ด์ฃผ์ด ์ด๊ธฐํ๋ฅผ ํด์ฃผ๊ณ start() ๋ฉ์๋๋ฅผ ๊ตฌํํด VC๋ก ๋ถํฐ ํ๋ฉด ์ ํ ์์ฒญ์ ๋ฐ์ผ๋ฉด, ์๋ต์ผ๋ก ์ฒซ ํ๋ฉด์ ๋์ธ ์ ์๋๋ก ํด์ค๋๋ค.
๊ฐ๋จํ ์์ ์ฝ๋๋ผ ๋ทฐ๋ชจ๋ธ์ ์ฌ์ฉํ์ง ์๋ ๋ฐฉ์์ผ๋ก ์์ฑํด์ฃผ์ด ๋ทฐ๋ชจ๋ธ์ ์ฃผ์ ํด์ฃผ๋ ์ฝ๋๊ฐ ์๋๋ฐ, ๋ทฐ๋ชจ๋ธ์ด ํ์ํ ๊ฒฝ์ฐ์๋ ViewController ์์ฑ์์ ์ ๋ทฐ๋ชจ๋ธ์ ์ฃผ์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค!!
๋ค์์ผ๋ก, MainViewController์ ๋ฒํผ์ ํด๋ฆญํ๊ฒ ๋๋ฉด ์ ์ ํ ํ๋ฉด์ผ๋ก ์ ํํด์ฃผ๊ธฐ ์ํด ์๋ก์ด ๋ฉ์๋ ์์ฑ์ด ํ์ํฉ๋๋ค.
ํด๋น ์์ ์์ ๋ฉ์ธ ๋ทฐ ๋ค์์ผ๋ก ์ค๋ ํ๋ก์ฐ์ ๋ํด์๋ ์์ ์ฝ๋๋ค์ดํฐ๋ค์ด ๊ด๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
์ด๋ฅผ ์ํด์ FirstCoordinator ๊ฐ์ฒด๋ฅผ ์์ฑํ ํ, ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ๋ฅผ self๋ก ์ค์ ํด์ฃผ๊ณ childCoordinators์ ์ถ๊ฐํด์ค๋๋ค.
๋ง์ง๋ง์ผ๋ก, start() ๋ฉ์๋๋ฅผ ํธ์ถํด์ฃผ์ด ํ๋ฉด ์ ํ ์์ฒญ ์ ๋ค์ ํ๋ฉด์ผ๋ก ์ ํํ ์ ์๋๋ก ํด์ค๋๋ค.
ChildCoordinator(FirstCoordinator, SecondCoordinator) ์ ์
class FirstCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
var navigationController: UINavigationController
weak var parentCoordinator: MainCoordinator?
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let firstViewController = FirstViewController()
firstViewController.coordinator = self
navigationController.pushViewController(firstViewController, animated: true)
}
func pushNextViewController() {
let nextViewController = FirstSubViewController()
nextViewController.coordinator = self
navigationController.pushViewController(nextViewController, animated: true)
}
}
Parent์ Child์ฌ์ด์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํด์ child๋ ๋ถ๋ชจ๋ฅผ ๊ธฐ์ตํ๊ณ ์์ด์ผ ํ๊ฒ ์ฃ ?
์ด ๋๋ฌธ์ ChildCoordinator๋ ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ๋ฅผ ํ๋กํผํฐ๋ก ๊ฐ์ ธ์ผ ํฉ๋๋ค.
ํ์ง๋ง ์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ ๋ถ๋ชจ ์ฝ๋๋ค์ดํฐ์ ์์ ์ฝ๋๋ค์ดํฐ๊ฐ ์๋ก๋ฅผ ์๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ ์ํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋๋๋ฐ, ์ด๋ weak ํค์๋๋ฅผ ๋ถ์ฌ ํด๊ฒฐํ ์ ์์ต๋๋ค.
FirstCoordinator(๋ฉ์ธ ์ฝ๋๋ค์ดํฐ์ ๋ํ ์์ ์ฝ๋๋ค์ดํฐ)์์๋ FirstViewController์ FirstSubViewController์ ๋ํ ํ๋ฉด ์ ํ ๋ก์ง์ ๊ด๋ฆฌํฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ๋ฉ์ธ ์ฝ๋๋ค์ดํฐ์์์ ๋๊ฐ์ด ํ๋ฉด์ ํ ์์ฒญ์ด ์ค๋ฉด ํ๋ฉด์ ์ ํํ ์ ์๋๋ก start()ํจ์๋ฅผ ๊ตฌํํด FirstViewController๋ก ์ด๋ํ ์ ์๋๋ก ํด์ฃผ๊ณ , pushNextViewController()๋ผ๋ ํจ์๋ฅผ ์ถ๊ฐ๋ก ์์ฑํด FirstSubViewController๋ก ์ด๋ํ ์ ์๋ ๋ก์ง๋ ๋ง๋ค์ด ์ฃผ์์ต๋๋ค.
SecondCoordinator๋ ๋์ผํ ๊ณผ์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํด์ฃผ๋ฉด ๋๋๋ฐ, SecondCoordinator๋ SecondViewController์ ๋ํ ํ๋ฉด ์ ํ ๋ก์ง๋ง์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ start() ๋ฉ์๋๋ง ๊ตฌํํด์ฃผ๋ฉด ๋๊ฒ ์ฃ ??
SceneDelegate ์ค์
์ด์ ์ฝ๋๋ค์ดํฐ์ ๋ํ ์ค๋น๋ ๋๋ฌ์ต๋๋ค. ์ฒซ ํ๋ฉด์ ๋์๋ด ์๋ค!!
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var mainCoordinator: MainCoordinator?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let navigationController = UINavigationController()
mainCoordinator = MainCoordinator(navigationController: navigationController)
mainCoordinator?.start()
self.window = UIWindow(windowScene: windowScene)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
}
์ฒซ ํ๋ฉด ์ค์ ์ SceneDelegate์์ ํด์ฃผ๋ฉด ๋๋๋ฐ์!(iOS13 ์ดํ๋ผ๋ฉด AppDelegate์์)
MainCoordinator ์์ฑ์ ์ํด ํ์ํ NavigationController ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก MainCoordinator ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
์ดํ, start() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ํด๋น NavigationController์ MainViewController๋ฅผ pushํฉ๋๋ค.
์ด๋ฅผ ํตํด ์ฑ์์ ๋ฐ์นญ์ด ๋๋๋ฉด ์ฒซ ํ๋ฉด์ธ MainViewController๊ฐ ํ๋ฉด์ ๋ณด์ฌ์ง๊ฒ ๋ฉ๋๋ค!
MainViewController ์ค์
๊ทธ๋ ๋ค๋ฉด ํ์ฌ ํ๋ฉด์์ ๋ค์ ํ๋ฉด์ผ๋ก ์ ํํ๊ธฐ ์ํด VC์์ ์ฝ๋๋ค์ดํฐ๋ก ์ด๋ป๊ฒ ํ๋ฉด ์ ํ ์์ฒญ์ ๋ณด๋ด๋์ง ์ดํด๋ด ์๋ค!
class MainViewController: UIViewController {
// MARK: Properties
private let firstButton = UIButton()
private let secondButton = UIButton()
weak var coordinator: MainCoordinator?
let disposeBag = DisposeBag()
// MARK: Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
setStyle()
setLayout()
tapButtonAction()
}
// MARK: UI
private func setStyle() {
// UI ์ค์
}
private func setLayout() {
// ๋ ์ด์์ ์ค์
}
// MARK: Action
private func tapButtonAction() {
firstButton.rx.tap.asDriver(onErrorJustReturn: ())
.drive(onNext: { [weak self] in
self?.coordinator?.pushFirstViewController()
})
.disposed(by: disposeBag)
secondButton.rx.tap.asDriver(onErrorJustReturn: ())
.drive(onNext: { [weak self] in
self?.coordinator?.pushSecondViewController()
})
.disposed(by: disposeBag)
}
}
๋ฒํผ์ ๋ ๊ฐ ๋ง๋ค๊ณ RxCocoa๋ฅผ ์ด์ฉํด ํด๋น ๋ฒํผ๋ค์ ํฐ์น ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํ์ต๋๋ค.
๋ฒํผ์ ํฐ์น ์ด๋ฒคํธ๊ฐ ๋ฐฉ์ถ๋๊ฒ ๋๋ฉด coordinator์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ํ๋ ํ๋ฉด์ผ๋ก ์ ํํด์ค๋๋ค! (๋ทฐ๋ชจ๋ธ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋ทฐ๋ชจ๋ธ์ด VC์ ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํ๋ ํํ์ด๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ค์ดํฐ์ ๋ฉ์๋ ํธ์ถ์ ๋ทฐ๋ชจ๋ธ์์ ํ๊ฒ ๋ฉ๋๋ค)
ํ์ฌ๊น์ง์ ํ๋ฉด ์ ํ ๊ณผ์ ์ ์ ๋ฆฌํ์๋ฉด, MainViewController๋ฅผ ์ฒ์์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ MainCoordinator๊ฐ ๋ด๋นํ๊ณ ์์ผ๋ฉฐ, MainViewController์์ First, SecondViewController๋ก์ ์ด๋์ ๊ฐ๊ฐ FirstViewCoordinator, SecondViewCoordinator๊ฐ ๋ด๋นํ๊ณ ์์ต๋๋ค. (MainCoordinator.push~VC() → ~ViewCoordinator.start()์ ํ๋ฆ์ผ๋ก ๋์)
FirstViewController ์ค์
๋ง์ง๋ง์ผ๋ก FirstViewController์์ FirstSubViewController์ ํ๋ฉด์ ํ์ ์ดํด๋ด ์๋ค.
class FirstViewController: UIViewController {
// MARK: Properties
private let titleLabel = UILabel()
private let nextButton = UIButton()
weak var coordinator: FirstCoordinator?
let disposeBag = DisposeBag()
// MARK: Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
setStyle()
setLayout()
tapButtonAction()
}
// MARK: UI
private func setStyle() {
// UI ์ค์
}
private func setLayout() {
// ๋ ์ด์์ ์ค์
}
// MARK: Action
private func tapButtonAction() {
nextButton.rx.tap.asDriver(onErrorJustReturn: ())
.drive(onNext: { [weak self] in
self?.coordinator?.pushNextViewController()
})
.disposed(by: disposeBag)
}
}
์์์ ํ๋ ๊ฒ๊ณผ ๋์ผํ ๋ฐฉ์์ผ๋ก RxCocoa๋ฅผ ์ด์ฉํด ํด๋น ๋ฒํผ์ ํฐ์น ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋ ํด ์ด๋ฒคํธ ๋ฐฉ์ถ ์ coordinator์ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ค์ ํ๋ฉด์ผ๋ก ์ ํํด์ค๋๋ค. ๋ฐฉ์์ ๋์ผํ์ง๋ง, ๋ค์ ํ๋ฉด์ธ FirstSubViewController๋ก์ ์ด๋์ ๋์ผํ ์ฝ๋๋ค์ดํฐ(=FirstCoordinator)๊ฐ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์๋ pushNextViewController() ํจ์ ํธ์ถ ์ ๋ณ๋์ ์ฝ๋๋ค์ดํฐ ์์ฑ ์์ด ํ๋ฉด์ ํ์ด ์ด๋ฃจ์ด ์ง๋ค๋ ์ ์ด ์์์ ๋ดค๋ ํ๋ฉด ์ ํ ๊ณผ์ ์ฐจ์ด์ ์ ๋๋ค!
์ ์ฒด์ ์ผ๋ก ์ด๋ป๊ฒ ํ๋ฉด ์ ํ์ด ์ด๋ฃจ์ด์ง๊ณ ์๋์ง ๊ทธ๋ฆผ๊ณผ ์์ ์ฝ๋๋ก ์ดํด๊ฐ ๋์ จ๊ธธ ๋ฐ๋ผ๋ฉฐ,,
์ ์ฒด ์ฝ๋๋ ๊ฐ์ด ์ฒจ๋ถํ๋๋ก ํ๊ฒ ์ต๋๋ค!!
์ ์ฒด ์ฝ๋
https://github.com/jane1choi/Coordinator-Practice
์์ ๋งํฌ์์ ์ ์ฒด ์ฝ๋๋ฅผ ํ์ธํ์ค ์ ์์ต๋๋ค!
๋ค์ ํฌ์คํ ์์๋ ์ค์ ํ๋ก์ ํธ์ ์ด๋ป๊ฒ ์ ์ฉํ๋์ง ์ข ๋ ๋ณต์กํ ํ๋ก์ฐ์ ํ๋ฉด์ ํ ์์๋ฅผ ๊ฐ์ ธ์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค!!
๋ถ์กฑํ ์ ์ด ๋ง์ ๊ธ์ด๋ ์กฐ์ธ์ด๋ ์ง์ ํ์ํฉ๋๋ค๐๐
๊ธด ๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!!
[์ฐธ๊ณ ์๋ฃ]
'๐ iOS > iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] TDD์ Unit Test (3) | 2023.12.14 |
---|---|
[iOS] iOS ํ์ผ ์์คํ (1) | 2023.11.28 |
[iOS] ํค์ฒด์ธ(Keychain)์ ์ด์ฉํ ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ (0) | 2023.08.06 |
[iOS] ReactorKit์ด๋? (4) | 2022.08.03 |
[iOS] UserDefaults๋? (3) | 2022.01.06 |