diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/AppCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/AppCoordinator.swift index 4ee646c..533ab8b 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/AppCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/AppCoordinator.swift @@ -45,8 +45,17 @@ final class AppCoordinator: BaseCoordinator { private extension AppCoordinator { func setLoginRootVC() { - let vc = viewControllerFactory.makeLoginVC() - router.setRoot(vc, animated: true) + let coordinator = coordinatorFactory.makeLoginCoordinator( + router: router, + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory + ) + coordinator.onFinish = { [weak self, weak coordinator] in + self?.removeDependency(coordinator) + self?.start() + } + self.addDependency(coordinator) + coordinator.start() } func setTabBarRootVC() { diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/ClipCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/ClipCoordinator.swift index d723d31..f4a251d 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/ClipCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/ClipCoordinator.swift @@ -7,16 +7,22 @@ import Foundation -final class ClipCoordinator: BaseCoordinator { +final class ClipCoordinator: BaseCoordinator, CoordinatorFinishOutput { + + var onFinish: (() -> Void)? + private let router: RouterProtocol private let viewControllerFactory: ViewControllerFactoryProtocol + private let coordinatorFactory: CoordinatorFactoryProtocol init( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) { self.router = router self.viewControllerFactory = viewControllerFactory + self.coordinatorFactory = coordinatorFactory } override func start() { @@ -30,6 +36,9 @@ private extension ClipCoordinator { vc.onEditClipSelected = { [weak self] clipList in self?.showEditClipVC(clipList: clipList) } + vc.onClipItemSelected = { [weak self] clipId, clipName in + self?.showDetailClipVC(id: clipId, name: clipName) + } router.setRoot(vc, animated: false) } @@ -38,4 +47,10 @@ private extension ClipCoordinator { vc.setupDataBind(clipModel: clipList) router.push(vc, animated: false, hideBottomBarWhenPushed: true) } + + func showDetailClipVC(id: Int, name: String) { + let vc = viewControllerFactory.makeDetailClipVC() + vc.setupCategory(id: id, name: name) + router.push(vc, animated: true) + } } diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/HomeCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/HomeCoordinator.swift index 53adff1..aa6192b 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/HomeCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/HomeCoordinator.swift @@ -7,16 +7,22 @@ import Foundation -final class HomeCoordinator: BaseCoordinator { +final class HomeCoordinator: BaseCoordinator, CoordinatorFinishOutput { + + var onFinish: (() -> Void)? + private let router: RouterProtocol private let viewControllerFactory: ViewControllerFactoryProtocol + private let coordinatorFactory: CoordinatorFactoryProtocol init( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) { self.router = router self.viewControllerFactory = viewControllerFactory + self.coordinatorFactory = coordinatorFactory } override func start() { diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/LoginCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/LoginCoordinator.swift index edb780f..0bee216 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/LoginCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/LoginCoordinator.swift @@ -7,7 +7,10 @@ import UIKit -final class LoginCoordinator: BaseCoordinator { +final class LoginCoordinator: BaseCoordinator, CoordinatorFinishOutput { + + var onFinish: (() -> Void)? + private let router: RouterProtocol private let viewControllerFactory: ViewControllerFactoryProtocol private let coordinatorFactory: CoordinatorFactoryProtocol @@ -24,12 +27,13 @@ final class LoginCoordinator: BaseCoordinator { } override func start() { - showTabBarVC() + showLoginVC() } } private extension LoginCoordinator { - func showTabBarVC() { - + func showLoginVC() { + let vc = viewControllerFactory.makeLoginVC() + router.setRoot(vc, animated: true) } } diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/SearchCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/SearchCoordinator.swift index c748d57..38e0bc9 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/SearchCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/SearchCoordinator.swift @@ -7,16 +7,22 @@ import Foundation -final class SearchCoordinator: BaseCoordinator { +final class SearchCoordinator: BaseCoordinator, CoordinatorFinishOutput { + + var onFinish: (() -> Void)? + private let router: RouterProtocol private let viewControllerFactory: ViewControllerFactoryProtocol + private let coordinatorFactory: CoordinatorFactoryProtocol init( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) { self.router = router self.viewControllerFactory = viewControllerFactory + self.coordinatorFactory = coordinatorFactory } override func start() { diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift index 195d797..1fe37ad 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift @@ -62,7 +62,8 @@ private extension TabBarCoordinator { func startHomeCoordinator(navController: UINavigationController) { let coordinator = coordinatorFactory.makeHomeCoordinator( router: Router(rootViewController: navController), - viewControllerFactory: self.viewControllerFactory + viewControllerFactory: self.viewControllerFactory, + coordinatorFactory: coordinatorFactory ) self.addDependency(coordinator) coordinator.start() @@ -71,7 +72,8 @@ private extension TabBarCoordinator { func startClipCoordinator(navController: UINavigationController) { let coordinator = coordinatorFactory.makeClipCoordinator( router: Router(rootViewController: navController), - viewControllerFactory: self.viewControllerFactory + viewControllerFactory: self.viewControllerFactory, + coordinatorFactory: self.coordinatorFactory ) self.addDependency(coordinator) coordinator.start() @@ -80,7 +82,8 @@ private extension TabBarCoordinator { func startSearchCoordinator(navController: UINavigationController) { let coordinator = coordinatorFactory.makeSearchCoordinator( router: Router(rootViewController: navController), - viewControllerFactory: self.viewControllerFactory + viewControllerFactory: self.viewControllerFactory, + coordinatorFactory: self.coordinatorFactory ) self.addDependency(coordinator) coordinator.start() @@ -89,7 +92,8 @@ private extension TabBarCoordinator { func startTimerCoordinator(navController: UINavigationController) { let coordinator = coordinatorFactory.makeTimerCoordinator( router: Router(rootViewController: navController), - viewControllerFactory: self.viewControllerFactory + viewControllerFactory: self.viewControllerFactory, + coordinatorFactory: self.coordinatorFactory ) self.addDependency(coordinator) coordinator.start() diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/TimerCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/TimerCoordinator.swift index 6a0419d..1d29370 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/TimerCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/TimerCoordinator.swift @@ -7,16 +7,22 @@ import Foundation -final class TimerCoordinator: BaseCoordinator { +final class TimerCoordinator: BaseCoordinator, CoordinatorFinishOutput { + + var onFinish: (() -> Void)? + private let router: RouterProtocol private let viewControllerFactory: ViewControllerFactoryProtocol + private let coordinatorFactory: CoordinatorFactoryProtocol init( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) { self.router = router self.viewControllerFactory = viewControllerFactory + self.coordinatorFactory = coordinatorFactory } override func start() { diff --git a/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift b/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift index 090bb72..657af74 100644 --- a/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift +++ b/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift @@ -14,24 +14,34 @@ protocol CoordinatorFactoryProtocol { coordinatorFactory: CoordinatorFactoryProtocol ) -> TabBarCoordinator + func makeLoginCoordinator( + router: RouterProtocol, + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol + ) -> LoginCoordinator + func makeHomeCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> HomeCoordinator func makeClipCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> ClipCoordinator func makeSearchCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> SearchCoordinator func makeTimerCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> TimerCoordinator } @@ -48,43 +58,63 @@ final class CoordinatorFactory: CoordinatorFactoryProtocol { ) } + func makeLoginCoordinator( + router: RouterProtocol, + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol + ) -> LoginCoordinator { + return LoginCoordinator( + router: router, + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory + ) + } + func makeHomeCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> HomeCoordinator { return HomeCoordinator( router: router, - viewControllerFactory: viewControllerFactory + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory ) } func makeClipCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> ClipCoordinator { return ClipCoordinator( router: router, - viewControllerFactory: viewControllerFactory + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory ) } func makeSearchCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> SearchCoordinator { return SearchCoordinator( router: router, - viewControllerFactory: viewControllerFactory + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory ) } func makeTimerCoordinator( router: RouterProtocol, - viewControllerFactory: ViewControllerFactoryProtocol + viewControllerFactory: ViewControllerFactoryProtocol, + coordinatorFactory: CoordinatorFactoryProtocol ) -> TimerCoordinator { return TimerCoordinator( router: router, - viewControllerFactory: viewControllerFactory + viewControllerFactory: viewControllerFactory, + coordinatorFactory: coordinatorFactory ) } } diff --git a/TOASTER-iOS/Present/Clip/View/ClipViewController.swift b/TOASTER-iOS/Present/Clip/View/ClipViewController.swift index 2257469..af5201c 100644 --- a/TOASTER-iOS/Present/Clip/View/ClipViewController.swift +++ b/TOASTER-iOS/Present/Clip/View/ClipViewController.swift @@ -13,6 +13,11 @@ import Then final class ClipViewController: UIViewController { + // MARK: - View Controllable + + var onEditClipSelected: ((ClipModel) -> Void)? + var onClipItemSelected: ((Int, String) -> Void)? + // MARK: - UI Properties private let viewModel: ClipViewModel @@ -138,11 +143,13 @@ private extension ClipViewController { } func setupNavigationBar() { - let type: ToasterNavigationType = ToasterNavigationType(hasBackButton: false, - hasRightButton: true, - mainTitle: StringOrImageType.string(StringLiterals.Tabbar.clip), - rightButton: StringOrImageType.string("편집"), - rightButtonAction: editButtonTapped) + let type: ToasterNavigationType = ToasterNavigationType( + hasBackButton: false, + hasRightButton: true, + mainTitle: StringOrImageType.string(StringLiterals.Tabbar.clip), + rightButton: StringOrImageType.string("편집"), + rightButtonAction: editButtonTapped + ) if let navigationController = navigationController as? ToasterNavigationController { navigationController.setupNavigationBar(forType: type) @@ -150,10 +157,7 @@ private extension ClipViewController { } func editButtonTapped() { - let editClipViewController = ViewControllerFactory.shared.makeEditClipVC() - editClipViewController.setupDataBind(clipModel: viewModel.clipList) - editClipViewController.hidesBottomBarWhenPushed = true - self.navigationController?.pushViewController(editClipViewController, animated: false) + onEditClipSelected?(viewModel.clipList) } } @@ -161,15 +165,9 @@ private extension ClipViewController { extension ClipViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let nextVC = ViewControllerFactory.shared.makeDetailClipVC() - if indexPath.item == 0 { - nextVC.setupCategory(id: 0, name: "전체 클립") - } else { - nextVC.setupCategory(id: viewModel.clipList.clips[indexPath.item - 1].id, - name: viewModel.clipList.clips[indexPath.item - 1].title) - } - nextVC.hidesBottomBarWhenPushed = true - self.navigationController?.pushViewController(nextVC, animated: true) + let id = indexPath.item == 0 ? 0 : viewModel.clipList.clips[indexPath.item - 1].id + let title = indexPath.item == 0 ? "전체 클립" : viewModel.clipList.clips[indexPath.item - 1].title + onClipItemSelected?(id, title) } } diff --git a/TOASTER-iOS/Present/DetailClip/View/DetailClipViewController.swift b/TOASTER-iOS/Present/DetailClip/View/DetailClipViewController.swift index 1f2582c..12b3d23 100644 --- a/TOASTER-iOS/Present/DetailClip/View/DetailClipViewController.swift +++ b/TOASTER-iOS/Present/DetailClip/View/DetailClipViewController.swift @@ -23,20 +23,28 @@ final class DetailClipViewController: UIViewController { private let detailClipEmptyView = DetailClipEmptyView() private let detailClipListCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) - private lazy var linkOptionBottomSheetView = LinkOptionBottomSheetView(currentClipType: ClipType(categoryId: viewModel.categoryId)) - private lazy var optionBottom = ToasterBottomSheetViewController(bottomType: .gray, - bottomTitle: "더보기", - insertView: linkOptionBottomSheetView) + private lazy var linkOptionBottomSheetView = LinkOptionBottomSheetView( + currentClipType: ClipType(categoryId: viewModel.categoryId) + ) + private lazy var optionBottom = ToasterBottomSheetViewController( + bottomType: .gray, + bottomTitle: "더보기", + insertView: linkOptionBottomSheetView + ) private let editLinkBottomSheetView = EditLinkBottomSheetView() - private lazy var editLinkBottom = ToasterBottomSheetViewController(bottomType: .white, - bottomTitle: "링크 제목 편집", - insertView: editLinkBottomSheetView) + private lazy var editLinkBottom = ToasterBottomSheetViewController( + bottomType: .white, + bottomTitle: "링크 제목 편집", + insertView: editLinkBottomSheetView + ) private let changeClipBottomSheetView = ChangeClipBottomSheetView() - private lazy var changeClipBottom = ToasterBottomSheetViewController(bottomType: .gray, - bottomTitle: "클립을 선택해 주세요", - insertView: changeClipBottomSheetView) + private lazy var changeClipBottom = ToasterBottomSheetViewController( + bottomType: .gray, + bottomTitle: "클립을 선택해 주세요", + insertView: changeClipBottomSheetView + ) private lazy var firstToolTip = ToasterTipView( title: "링크를 다른 클립으로\n이동할 수 있어요!", @@ -158,10 +166,12 @@ private extension DetailClipViewController { } func setupNavigationBar() { - let type: ToasterNavigationType = ToasterNavigationType(hasBackButton: true, - hasRightButton: false, - mainTitle: StringOrImageType.string(viewModel.categoryName), - rightButton: StringOrImageType.string("어쩌구"), rightButtonAction: {}) + let type: ToasterNavigationType = ToasterNavigationType( + hasBackButton: true, + hasRightButton: false, + mainTitle: StringOrImageType.string(viewModel.categoryName), + rightButton: StringOrImageType.string("어쩌구"), rightButtonAction: {} + ) if let navigationController = navigationController as? ToasterNavigationController { navigationController.setupNavigationBar(forType: type) diff --git a/TOASTER-iOS/Present/Home/View/HomeViewController.swift b/TOASTER-iOS/Present/Home/View/HomeViewController.swift index e2b80dd..f749740 100644 --- a/TOASTER-iOS/Present/Home/View/HomeViewController.swift +++ b/TOASTER-iOS/Present/Home/View/HomeViewController.swift @@ -346,12 +346,13 @@ private extension HomeViewController { } func setupNavigationBar() { - let type: ToasterNavigationType = ToasterNavigationType(hasBackButton: false, - hasRightButton: true, - mainTitle: StringOrImageType.image(.wordmark), - rightButton: StringOrImageType.image(.icSettings24), - rightButtonAction: rightButtonTapped) - + let type: ToasterNavigationType = ToasterNavigationType( + hasBackButton: false, + hasRightButton: true, + mainTitle: StringOrImageType.image(.wordmark), + rightButton: StringOrImageType.image(.icSettings24), + rightButtonAction: rightButtonTapped + ) if let navigationController = navigationController as? ToasterNavigationController { navigationController.setupNavigationBar(forType: type) }