Created
May 1, 2020 01:19
-
-
Save jamesrochabrun/0efa6091b0002e70efb195cab1daf431 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TabBarController: UITabBarController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
/// 1 - Set view Controllers using `TabBarViewModel` | |
/// 2 - This iteration will create a master veiw controller embedded in a navigation controller for each tab. | |
/// 3 - `inSplitViewControllerIfSupported` is a `UINavigationController` extension method that will embed it in a `UISplitViewController` if supported. | |
/// we will see the implementation later. | |
viewControllers = TabBarViewModel.allCases.map { NavigationController(rootViewController: $0.masterViewController).inSplitViewControllerIfSupported(for: $0) } | |
} | |
} | |
/// The view model. | |
enum TabBarViewModel: String, CaseIterable { | |
case home | |
case search | |
case camera | |
case notifications | |
case profile | |
/// the tab bar icon | |
var icon: UIImage? { | |
switch self { | |
case .home: return UIImage(systemName: "house.fill") | |
case .search: return UIImage(systemName: "magnifyingglass") | |
case .camera: return UIImage(systemName: "plus.app") | |
case .notifications: return UIImage(systemName: "suit.heart") | |
case .profile: return UIImage(systemName: "person") | |
} | |
} | |
/// the tab bar title | |
var title: String { | |
rawValue | |
} | |
/// the master `topViewController` it instantiates a view controller using a convenient method for `UIStoryboards`. | |
var masterViewController: UIViewController { | |
switch self { | |
case .home: return HomeViewController.instantiate(from: "Main") | |
case .search: return SearchViewController.instantiate(from: "Main") | |
case .camera: return HomeViewController.instantiate(from: "Main") | |
case .notifications: return NotificationsViewController.instantiate(from: "Main") | |
case .profile: return UserProfileViewController.instantiate(from: "Main") | |
} | |
} | |
/// 4 - It defines if a tab should use a `UISplitViewController` as root or not. | |
var inSplitViewController: Bool { | |
switch self { | |
case .profile: | |
return true | |
default: | |
return false | |
} | |
} | |
} | |
extension UINavigationController { | |
/// 5 - This extension returns a `SplitViewController` instance with the master and an `EmptyDetailViewcontroller` instance | |
/// as a detail, if supported else will return self. | |
func inSplitViewControllerIfSupported(for viewModel: TabBarViewModel) -> UIViewController { | |
guard viewModel.inSplitViewController else { | |
self.tabBarItem.image = viewModel.icon | |
return self } | |
let splitViewController = SplitViewController(viewControllers: [self, EmptyDetailViewcontroller()]) | |
splitViewController.tabBarItem.image = viewModel.icon | |
return splitViewController | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment