'How to configure multiple view controllers to your main tab view controller
I am having issues configuring various view controllers to my main tab controller. After login I see a blank screen. This is partially due to my view controllers not being able to configure to the tab bar controller. I thought calling fetchUsers() and fetchDiscover() in the viewDidLoad would fix this issue. But, it seems to be a bit deeper than that. Maybe the issue is where I am declaring the variables user? and discover?. I just cant seem to figure it out. I would appreciate your ideas on how to solve this issue. Thank you in advance.
import UIKit
import Firebase
import YPImagePicker
import AVFoundation
import DropDown
class MainTabController: UITabBarController {
// MARK: - Lifecycle
var user: User? {
didSet {
guard let user = user else { return }
guard let discover = discover else { return }
configureViewControllers(withUser: user, withDiscover: discover)
}
}
var discover: Discover? {
didSet {
guard let discover = discover else { return }
guard let user = user else { return }
configureViewControllers(withUser: user, withDiscover: discover)
}
}
override func viewDidLoad() {
super.viewDidLoad()
checkIfUserIsLoggedIn()
fetchUser()
fetchDiscover()
}
//MARK: - Labels
class MyCell: DropDownCell {
let postLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 12)
label.textColor = .black
label.text = "Post"
let tap = UITapGestureRecognizer(target: self, action: #selector(pushToSelectDiscoverController))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)
return label
}()
let discoverLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 12)
label.textColor = .black
label.text = "Community"
let tap = UITapGestureRecognizer(target: self, action: #selector(pushToImagePicker))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)
return label
}()
}
// MARK: - API
func fetchUser() {
guard let uid = Auth.auth().currentUser?.uid else { return }
guard let discoverId = Auth.auth().currentUser?.uid else { return }
UserService.fetchUser(withUid: uid, withDiscoverId: discoverId) { user,discover in
self.user = user
self.discover = discover
}
}
func fetchDiscover() {
guard let discoverId = Auth.auth().currentUser?.uid else { return }
DiscoverService.fetchDiscover(withdiscoverId: discoverId) { discover, user in
self.discover = discover
}
}
func checkIfUserIsLoggedIn() {
if Auth.auth().currentUser == nil {
DispatchQueue.main.async {
let controller = LoginController()
controller.delegate = self
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: true, completion: nil)
}
}
}
// MARK: - Helpers
func configureViewControllers(withUser user: User, withDiscover discover: Discover) {
view.backgroundColor = .white
self.delegate = self
let layout = UICollectionViewFlowLayout()
let discoverFeed = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "Image-29"), selectedImage: #imageLiteral(resourceName: "Image-30"), rootViewController: DiscoverFeedController(collectionViewLayout: layout))
let search = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "search_unselected"), selectedImage: #imageLiteral(resourceName: "search_selected"), rootViewController: SearchController(config: .all, discConfig: .all))
let imageSelector = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "plus_unselected"), selectedImage: #imageLiteral(resourceName: "plus_unselected"), rootViewController: ImageSelectorController(currentUser: user))
let notifications = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "Image-37"), selectedImage: #imageLiteral(resourceName: "Image-36"), rootViewController: NotificationsController())
let profileController = ProfileController(user: user, discover: discover)
let profile = templateNavigationController(unselectedImage: #imageLiteral(resourceName: "profile_unselected"), selectedImage: #imageLiteral(resourceName: "profile_selected"), rootViewController: profileController)
viewControllers = [discoverFeed, search, imageSelector, notifications, profile]
tabBar.tintColor = .black
}
func templateNavigationController(unselectedImage: UIImage, selectedImage: UIImage, rootViewController: UIViewController) -> UINavigationController {
let nav = UINavigationController(rootViewController: rootViewController)
nav.tabBarItem.image = unselectedImage
nav.tabBarItem.selectedImage = selectedImage
nav.navigationBar.tintColor = .black
return nav
}
func didFinishPickingMediaForDiscover(_ picker: YPImagePicker) {
picker.didFinishPicking { items, _ in
picker.dismiss(animated: false) {
guard let discoverImage = items.singlePhoto?.image else { return }
let controller = UploadDiscoverController()
controller.discoverImage = discoverImage
controller.delegate = self
controller.currentUser = self.user
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: false, completion: nil)
}
}
}
func didFinishPickingMedia(_ picker: YPImagePicker) {
picker.didFinishPicking { items, _ in
picker.dismiss(animated: false) {
guard let selectedImage = items.singlePhoto?.image else { return }
let controller = UploadPostController()
controller.selectedImage = selectedImage
controller.delegate = self
controller.currentUser = self.user
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: false, completion: nil)
}
}
}
}
// MARK: - AuthenticationDelegate
extension MainTabController: AuthenticationDelegate {
func authenticationDidComplete() {
fetchUser()
self.dismiss(animated: true, completion: nil)
}
}
// MARK: - UITabBarControllerDelegate
extension MainTabController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
let index = viewControllers?.firstIndex(of: viewController)
if index == 2 {
dropDownMenu().self
}
return true
}
}
extension MainTabController: UploadPostControllerDelegate {
func controllerDidFinishUploadingPost(_ controller: UploadPostController) {
selectedIndex = 0
controller.dismiss(animated: true, completion: nil)
guard let feedNav = viewControllers?.first as? UINavigationController else { return }
guard let feed = feedNav.viewControllers.first as? FeedController else { return }
feed.handleRefresh()
}
}
extension MainTabController: UploadDiscoverControllerDelegate {
func controllerDidFinishUploadingDiscover(_ controller: UploadDiscoverController) {
selectedIndex = 0
controller.dismiss(animated: true, completion: nil)
guard let discoverFeedNav = viewControllers?.first as? UINavigationController else { return }
guard let discoverFeed = discoverFeedNav.viewControllers.first as? DiscoverFeedController else { return }
}
}
extension MainTabController {
func dropDownMenu() {
let dropDown = DropDown(frame: CGRect(x: 110, y: 140, width: 30, height: 30))
dropDown.anchorView = tabBar
dropDown.dataSource = ["Post", "Discover"]
dropDown.direction = .top
dropDown.dismissMode = .automatic
dropDown.cellNib = UINib(nibName: "MyCell", bundle: nil)
dropDown.customCellConfiguration = { (index: Index, item: String, cell: DropDownCell) -> Void in
guard let cell = cell as? MyCell else { return }
cell.discoverLabel.isUserInteractionEnabled = true
cell.postLabel.isUserInteractionEnabled = true
}
}
}
extension MainTabController {
@objc func pushToImagePicker() -> Bool {
var config = YPImagePickerConfiguration()
config.library.mediaType = .photo
//config.library.mediaType = .video
config.shouldSaveNewPicturesToAlbum = false
config.startOnScreen = .library
config.screens = [.library]
config.hidesStatusBar = false
config.hidesBottomBar = false
config.library.maxNumberOfItems = 5
let picker = YPImagePicker(configuration: config)
picker.modalPresentationStyle = .fullScreen
present(picker, animated: true, completion: nil)
didFinishPickingMedia(picker)
return true
}
}
extension MainTabController {
@objc func pushToSelectDiscoverController() {
SelectDiscoverService.showSelectDiscover(toUid: user?.uid, fromDiscover: discover, fromUser: user) { discover in
let controller = SelectDiscoverController(user: self.user, discover: discover)
self.navigationController?.pushViewController(controller, animated: true)
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
