From 53aeadb18a7ffdb3654c68d884a95aaf228ef604 Mon Sep 17 00:00:00 2001 From: Philips Jose Date: Fri, 13 Mar 2026 17:21:42 +0530 Subject: [PATCH 1/4] Started corrdinator setup --- Chess/Coordinators/MainCoordinator.swift | 29 ++++++++-- Chess/Coordinators/PlayCoordinator.swift | 3 +- Chess/Coordinators/ProfileCoordinator.swift | 3 +- Chess/MVVM/View/MainTabBarController.swift | 61 --------------------- Chess/MVVM/View/SplashViewController.swift | 6 +- 5 files changed, 34 insertions(+), 68 deletions(-) delete mode 100644 Chess/MVVM/View/MainTabBarController.swift diff --git a/Chess/Coordinators/MainCoordinator.swift b/Chess/Coordinators/MainCoordinator.swift index 7e983d7..ee7a81e 100644 --- a/Chess/Coordinators/MainCoordinator.swift +++ b/Chess/Coordinators/MainCoordinator.swift @@ -11,16 +11,30 @@ protocol Coordinator: AnyObject { func start() } +enum TabBar: Int, CaseIterable { + case play, profile, settings + var title: String { + return Strings.TabBarTitles[self.rawValue] + } + + var imageName: String { + return SystemImageNames.TabBarImages[self.rawValue] + } + + var systemImage: UIImage? { + return UIImage(systemName: self.imageName) + } +} + class MainCoordinator: Coordinator { - var navigationController: UINavigationController // Not used for tabs, but required by protocol + var navigationController: UINavigationController = UINavigationController() // Not used for tabs, but required by protocol var tabBarController: UITabBarController // Keep track of child coordinators so they aren't deallocated var childCoordinators = [Coordinator]() - init(navigationController: UINavigationController) { - self.navigationController = navigationController - self.tabBarController = UITabBarController() + init(tabBarController: UITabBarController) { + self.tabBarController = tabBarController } func start() { @@ -43,6 +57,13 @@ class MainCoordinator: Coordinator { self.tabBarController.viewControllers = [playNav, profileNav] } + private func createNav(with item: TabBar) -> UINavigationController { + let nav = UINavigationController() + nav.tabBarItem.image = item.systemImage + nav.isNavigationBarHidden = true + return nav + } + private func configureAppearance() { self.tabBarController.tabBar.tintColor = .link self.tabBarController.tabBar.unselectedItemTintColor = .lightGray diff --git a/Chess/Coordinators/PlayCoordinator.swift b/Chess/Coordinators/PlayCoordinator.swift index 3a53c31..66c2da6 100644 --- a/Chess/Coordinators/PlayCoordinator.swift +++ b/Chess/Coordinators/PlayCoordinator.swift @@ -13,7 +13,8 @@ class PlayCoordinator: Coordinator { init(navigationController: UINavigationController) { self.navigationController = navigationController // Configure the tab bar item here - navigationController.tabBarItem = UITabBarItem(title: "Settings", image: UIImage(systemName: "gear"), tag: 1) + navigationController.isNavigationBarHidden = true + navigationController.tabBarItem.image = TabBar.play.systemImage } func start() { diff --git a/Chess/Coordinators/ProfileCoordinator.swift b/Chess/Coordinators/ProfileCoordinator.swift index fc59d81..3854d1e 100644 --- a/Chess/Coordinators/ProfileCoordinator.swift +++ b/Chess/Coordinators/ProfileCoordinator.swift @@ -13,7 +13,8 @@ class ProfileCoordinator: Coordinator { init(navigationController: UINavigationController) { self.navigationController = navigationController // Configure the tab bar item here - navigationController.tabBarItem = UITabBarItem(title: "Settings", image: UIImage(systemName: "gear"), tag: 1) + navigationController.isNavigationBarHidden = true + navigationController.tabBarItem.image = TabBar.profile.systemImage } func start() { diff --git a/Chess/MVVM/View/MainTabBarController.swift b/Chess/MVVM/View/MainTabBarController.swift deleted file mode 100644 index e7dd70f..0000000 --- a/Chess/MVVM/View/MainTabBarController.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// MainTabBarController.swift -// Chess -// -// Created by Philips Jose on 29/01/26. -// - -import UIKit - -enum TabBar: Int, CaseIterable { - case play, profile, settings - var title: String { - return Strings.TabBarTitles[self.rawValue] - } - - var imageName: String { - return SystemImageNames.TabBarImages[self.rawValue] - } - - var systemImage: UIImage? { - return UIImage(systemName: self.imageName) - } -} - -class MainTabBarController: UITabBarController { - - override func viewDidLoad() { - super.viewDidLoad() - setupTabs() - configureAppearance() - } - - private func setupTabs() { - let playVC = UIStoryboard.instantiate(ModeSelectionViewController.self, from: Storyboards.main) - let profileVC = UIStoryboard.instantiate(ProfileViewController.self, from: Storyboards.profile) - - let nav1 = createNav(with: TabBar.play, vc: playVC) - let nav2 = createNav(with: TabBar.profile, vc: profileVC) - - setViewControllers([nav1, nav2], animated: true) - } - - private func createNav(with item: TabBar, vc: UIViewController) -> UINavigationController { - let nav = UINavigationController(rootViewController: vc) - nav.tabBarItem.image = item.systemImage - nav.isNavigationBarHidden = true - return nav - } - - private func configureAppearance() { - tabBar.tintColor = .link - tabBar.unselectedItemTintColor = .lightGray - - let appearance = UITabBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.backgroundColor = .secondarySystemBackground - - tabBar.standardAppearance = appearance - tabBar.scrollEdgeAppearance = appearance - } -} diff --git a/Chess/MVVM/View/SplashViewController.swift b/Chess/MVVM/View/SplashViewController.swift index a86941b..c772bac 100644 --- a/Chess/MVVM/View/SplashViewController.swift +++ b/Chess/MVVM/View/SplashViewController.swift @@ -31,6 +31,10 @@ class SplashViewController: UIViewController { private func navigateToNextPage() { guard let window = view.window else { return } - window.rootViewController = MainTabBarController() + let tabBarController = UITabBarController() + let coordinator = MainCoordinator(tabBarController: tabBarController) + coordinator.start() + window.rootViewController = tabBarController + window.makeKeyAndVisible() } } From b1e2ddd4340e797fff901f0e33924ca81b44481c Mon Sep 17 00:00:00 2001 From: Philips Jose Date: Tue, 17 Mar 2026 14:54:12 +0530 Subject: [PATCH 2/4] Added coordinator reference to chess vc --- Chess/Coordinators/PlayCoordinator.swift | 1 + Chess/MVVM/View/{Chess => Play}/CapturedPieceCell.swift | 0 .../MVVM/View/{Chess => Play}/ChessBoardCollectionViewCell.swift | 0 Chess/MVVM/View/{Chess => Play}/ChessViewController.swift | 1 + Chess/MVVM/View/{ => Play}/ModeSelectionViewController.swift | 0 5 files changed, 2 insertions(+) rename Chess/MVVM/View/{Chess => Play}/CapturedPieceCell.swift (100%) rename Chess/MVVM/View/{Chess => Play}/ChessBoardCollectionViewCell.swift (100%) rename Chess/MVVM/View/{Chess => Play}/ChessViewController.swift (99%) rename Chess/MVVM/View/{ => Play}/ModeSelectionViewController.swift (100%) diff --git a/Chess/Coordinators/PlayCoordinator.swift b/Chess/Coordinators/PlayCoordinator.swift index 66c2da6..0e216de 100644 --- a/Chess/Coordinators/PlayCoordinator.swift +++ b/Chess/Coordinators/PlayCoordinator.swift @@ -25,6 +25,7 @@ class PlayCoordinator: Coordinator { func showChessVC() { let vc = UIStoryboard.instantiate(ChessViewController.self, from: Storyboards.main) + vc.coordinator = self navigationController.pushViewController(vc, animated: true) } } diff --git a/Chess/MVVM/View/Chess/CapturedPieceCell.swift b/Chess/MVVM/View/Play/CapturedPieceCell.swift similarity index 100% rename from Chess/MVVM/View/Chess/CapturedPieceCell.swift rename to Chess/MVVM/View/Play/CapturedPieceCell.swift diff --git a/Chess/MVVM/View/Chess/ChessBoardCollectionViewCell.swift b/Chess/MVVM/View/Play/ChessBoardCollectionViewCell.swift similarity index 100% rename from Chess/MVVM/View/Chess/ChessBoardCollectionViewCell.swift rename to Chess/MVVM/View/Play/ChessBoardCollectionViewCell.swift diff --git a/Chess/MVVM/View/Chess/ChessViewController.swift b/Chess/MVVM/View/Play/ChessViewController.swift similarity index 99% rename from Chess/MVVM/View/Chess/ChessViewController.swift rename to Chess/MVVM/View/Play/ChessViewController.swift index f272081..9e01295 100644 --- a/Chess/MVVM/View/Chess/ChessViewController.swift +++ b/Chess/MVVM/View/Play/ChessViewController.swift @@ -13,6 +13,7 @@ class ChessViewController: UIViewController { @IBOutlet private weak var boardCollectionView: UICollectionView! @IBOutlet private weak var playerTwoCollectionView: UICollectionView! + weak var coordinator: Coordinator? public let viewModel = ChessViewModel() override func viewDidLoad() { diff --git a/Chess/MVVM/View/ModeSelectionViewController.swift b/Chess/MVVM/View/Play/ModeSelectionViewController.swift similarity index 100% rename from Chess/MVVM/View/ModeSelectionViewController.swift rename to Chess/MVVM/View/Play/ModeSelectionViewController.swift From 3c6e0c57e1298ac9e4da00376b97b20f1111540c Mon Sep 17 00:00:00 2001 From: Philips Jose Date: Tue, 17 Mar 2026 18:02:40 +0530 Subject: [PATCH 3/4] Used coordinator pattern to enter chessvc --- Chess/App/SceneDelegate.swift | 2 +- Chess/Coordinators/PlayCoordinator.swift | 1 + Chess/Coordinators/ProfileCoordinator.swift | 1 + Chess/MVVM/View/Play/ModeSelectionViewController.swift | 6 ++---- Chess/MVVM/View/Settings/SettingsViewController.swift | 1 + Chess/MVVM/View/SplashViewController.swift | 3 ++- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Chess/App/SceneDelegate.swift b/Chess/App/SceneDelegate.swift index 4063932..719359a 100644 --- a/Chess/App/SceneDelegate.swift +++ b/Chess/App/SceneDelegate.swift @@ -10,7 +10,7 @@ import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - + var coordinator: Coordinator? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. diff --git a/Chess/Coordinators/PlayCoordinator.swift b/Chess/Coordinators/PlayCoordinator.swift index 0e216de..f4f9c77 100644 --- a/Chess/Coordinators/PlayCoordinator.swift +++ b/Chess/Coordinators/PlayCoordinator.swift @@ -26,6 +26,7 @@ class PlayCoordinator: Coordinator { func showChessVC() { let vc = UIStoryboard.instantiate(ChessViewController.self, from: Storyboards.main) vc.coordinator = self + vc.hidesBottomBarWhenPushed = true navigationController.pushViewController(vc, animated: true) } } diff --git a/Chess/Coordinators/ProfileCoordinator.swift b/Chess/Coordinators/ProfileCoordinator.swift index 3854d1e..4f71fce 100644 --- a/Chess/Coordinators/ProfileCoordinator.swift +++ b/Chess/Coordinators/ProfileCoordinator.swift @@ -25,6 +25,7 @@ class ProfileCoordinator: Coordinator { func showSettings() { let vc = UIStoryboard.instantiate(SettingsViewController.self, from: Storyboards.settings) + vc.coordinator = self navigationController.pushViewController(vc, animated: true) } } diff --git a/Chess/MVVM/View/Play/ModeSelectionViewController.swift b/Chess/MVVM/View/Play/ModeSelectionViewController.swift index 6fec956..3376874 100644 --- a/Chess/MVVM/View/Play/ModeSelectionViewController.swift +++ b/Chess/MVVM/View/Play/ModeSelectionViewController.swift @@ -20,7 +20,7 @@ class ModeSelectionViewController: UIViewController { @IBOutlet private weak var navBar: UIView! @IBOutlet private weak var titleLabel: UILabel! - weak var coordinator: Coordinator? + weak var coordinator: PlayCoordinator? private var optionButtons: [UIButton] = [] private let stackView: UIStackView = { @@ -89,9 +89,7 @@ class ModeSelectionViewController: UIViewController { let mode = PlayerMode.allCases.first(where: {$0.string == text}) { AppPreferences.shared.currentPlayerMode = mode if mode == .passAndPlay { - let chessVC = UIStoryboard.instantiate(ChessViewController.self, from: Storyboards.main) - chessVC.hidesBottomBarWhenPushed = true - self.navigationController?.pushViewController(chessVC, animated: true) + self.coordinator?.showChessVC() } else { self.showAlert(title: Strings.vsComputerAlert.title, message: Strings.vsComputerAlert.description) } diff --git a/Chess/MVVM/View/Settings/SettingsViewController.swift b/Chess/MVVM/View/Settings/SettingsViewController.swift index 0ee818b..1d095dd 100644 --- a/Chess/MVVM/View/Settings/SettingsViewController.swift +++ b/Chess/MVVM/View/Settings/SettingsViewController.swift @@ -11,6 +11,7 @@ class SettingsViewController: UIViewController { @IBOutlet private weak var tableView: UITableView! + weak var coordinator: ProfileCoordinator? private let viewModel = SettingsViewModel() override func viewDidLoad() { diff --git a/Chess/MVVM/View/SplashViewController.swift b/Chess/MVVM/View/SplashViewController.swift index c772bac..8d416fd 100644 --- a/Chess/MVVM/View/SplashViewController.swift +++ b/Chess/MVVM/View/SplashViewController.swift @@ -30,10 +30,11 @@ class SplashViewController: UIViewController { } private func navigateToNextPage() { - guard let window = view.window else { return } + guard let window = view.window, let delegate = view.window?.windowScene?.delegate as? SceneDelegate else { return } let tabBarController = UITabBarController() let coordinator = MainCoordinator(tabBarController: tabBarController) coordinator.start() + delegate.coordinator = coordinator window.rootViewController = tabBarController window.makeKeyAndVisible() } From 4ed440587cfb369da0d1d111ef28d1562d53df42 Mon Sep 17 00:00:00 2001 From: Philips Jose Date: Tue, 17 Mar 2026 18:14:02 +0530 Subject: [PATCH 4/4] Applied coordiantor pattern everywhere --- Chess/Coordinators/ProfileCoordinator.swift | 10 ++++++++-- Chess/MVVM/View/Profile/ProfileViewController.swift | 6 ++---- Chess/MVVM/View/Settings/SettingsViewController.swift | 7 ++----- Chess/MVVM/ViewModel/SettingsViewModel.swift | 5 +++++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Chess/Coordinators/ProfileCoordinator.swift b/Chess/Coordinators/ProfileCoordinator.swift index 4f71fce..4057566 100644 --- a/Chess/Coordinators/ProfileCoordinator.swift +++ b/Chess/Coordinators/ProfileCoordinator.swift @@ -20,12 +20,18 @@ class ProfileCoordinator: Coordinator { func start() { let vc = UIStoryboard.instantiate(ProfileViewController.self, from: Storyboards.profile) vc.coordinator = self - navigationController.pushViewController(vc, animated: false) + self.navigationController.pushViewController(vc, animated: false) } func showSettings() { let vc = UIStoryboard.instantiate(SettingsViewController.self, from: Storyboards.settings) vc.coordinator = self - navigationController.pushViewController(vc, animated: true) + self.navigationController.pushViewController(vc, animated: true) + } + + func showSettings(of setting: SettingsDestination) { + let vc = UIStoryboard.instantiate(SettingsDetailViewController.self, from: Storyboards.settings) + vc.viewModel.currentSetting = setting + self.navigationController.pushViewController(vc, animated: true) } } diff --git a/Chess/MVVM/View/Profile/ProfileViewController.swift b/Chess/MVVM/View/Profile/ProfileViewController.swift index 7c737d4..4cb61cd 100644 --- a/Chess/MVVM/View/Profile/ProfileViewController.swift +++ b/Chess/MVVM/View/Profile/ProfileViewController.swift @@ -11,7 +11,7 @@ class ProfileViewController: UIViewController { @IBOutlet private weak var tableView: UITableView! - weak var coordinator: Coordinator? + weak var coordinator: ProfileCoordinator? private let viewModel = ProfileViewModel() override func viewDidLoad() { @@ -31,9 +31,7 @@ class ProfileViewController: UIViewController { } @IBAction func settingsButtonTapped(_ sender: Any) { - let settingsVC = UIStoryboard.instantiate(SettingsViewController.self, from: Storyboards.settings) - settingsVC.hidesBottomBarWhenPushed = true - self.navigationController?.pushViewController(settingsVC, animated: true) + coordinator?.showSettings() } } diff --git a/Chess/MVVM/View/Settings/SettingsViewController.swift b/Chess/MVVM/View/Settings/SettingsViewController.swift index 1d095dd..618bfb2 100644 --- a/Chess/MVVM/View/Settings/SettingsViewController.swift +++ b/Chess/MVVM/View/Settings/SettingsViewController.swift @@ -73,12 +73,9 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) - let setting = self.viewModel.sections[indexPath.section].items[indexPath.row] + let setting = self.viewModel.getSettings(at: indexPath) if setting.details.type == .navigation { - let vc = UIStoryboard.instantiate(SettingsDetailViewController.self, from: Storyboards.settings) - vc.viewModel.currentSetting = setting - self.navigationController?.pushViewController(vc, animated: true) - + coordinator?.showSettings(of: setting) } } } diff --git a/Chess/MVVM/ViewModel/SettingsViewModel.swift b/Chess/MVVM/ViewModel/SettingsViewModel.swift index 1e213d5..c25ac37 100644 --- a/Chess/MVVM/ViewModel/SettingsViewModel.swift +++ b/Chess/MVVM/ViewModel/SettingsViewModel.swift @@ -4,6 +4,7 @@ // // Created by Philips Jose on 30/01/26. // +import Foundation enum SettingType { case toggle @@ -63,4 +64,8 @@ class SettingsViewModel { public func setupData() { sections = SettingsSection.allCases } + + public func getSettings(at indexPath: IndexPath) -> SettingsDestination { + return sections[indexPath[0]].items[indexPath[1]] + } }