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/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..f4f9c77 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() { @@ -24,6 +25,8 @@ 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 fc59d81..4057566 100644 --- a/Chess/Coordinators/ProfileCoordinator.swift +++ b/Chess/Coordinators/ProfileCoordinator.swift @@ -13,17 +13,25 @@ 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() { 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) - navigationController.pushViewController(vc, animated: true) + vc.coordinator = self + 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/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/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 92% rename from Chess/MVVM/View/ModeSelectionViewController.swift rename to Chess/MVVM/View/Play/ModeSelectionViewController.swift index 6fec956..3376874 100644 --- a/Chess/MVVM/View/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/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 0ee818b..618bfb2 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() { @@ -72,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/View/SplashViewController.swift b/Chess/MVVM/View/SplashViewController.swift index a86941b..8d416fd 100644 --- a/Chess/MVVM/View/SplashViewController.swift +++ b/Chess/MVVM/View/SplashViewController.swift @@ -30,7 +30,12 @@ class SplashViewController: UIViewController { } private func navigateToNextPage() { - guard let window = view.window else { return } - window.rootViewController = MainTabBarController() + 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() } } 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]] + } }