i have a UITabBarViewController that i have created programmatically and i had imported all my 3 UIViewControllers , Now I wanna add Coordinator to my Project and i want to add Coordinator to all my 3 UIViewControllers.
how can i Use It?
class MainTabbarViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// home Tab
let homeStoryboard: UIStoryboard = UIStoryboard(name: "HomeStoryboard", bundle: nil)
let homeTab = homeStoryboard.instantiateViewController(withIdentifier: "HomeViewController")
let homeTabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), selectedImage: UIImage(systemName: "house.fill"))
homeTab.tabBarItem = homeTabBarItem
// search Tab
let searchStoryboard: UIStoryboard = UIStoryboard(name: "SearchStoryboard", bundle: nil)
let searchTab = searchStoryboard.instantiateViewController(withIdentifier: "SearchViewController")
let searchTabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass"), selectedImage: UIImage(systemName: "magnifyingglass"))
searchTab.tabBarItem = searchTabBarItem
// profile Tab
let profileStoryboard: UIStoryboard = UIStoryboard(name: "ProfileStoryboard", bundle: nil)
let profileTab = profileStoryboard.instantiateViewController(withIdentifier: "ProfileViewController")
let profileTabBarItem = UITabBarItem(title: "Profile", image: UIImage(systemName: "person"), selectedImage: UIImage(systemName: "person.fill"))
profileTab.tabBarItem = profileTabBarItem
profileTab.navigationController?.navigationBar.isHidden = true
self.tabBar.tintColor = UIColor(asset: Asset.Colors.yellow)
self.viewControllers = [homeTab, searchTab, profileTab]
}
}
this is my UITabBarController
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
and this is my Coordinator protocol.
this file should remove and add an other file.
i named TabCoordinator with this Code:
final class TabCoordinator: NSObject, TabBarCoordinatorProtocol {
// Root View Controller
var rootViewController: UIViewController {
return tabController
}
// Empty UITabBarController
let tabController: UITabBarController
// Tab Item Coordinators
let homeCoordinator: HomeCoordinator
let searchCoordinator: SearchCoordinator
let profileCoordinator: ProfileCoordinator
// Initialize
override init() {
tabController = UITabBarController()
var controllers: [UIViewController] = []
// Home Coordinator
homeCoordinator = HomeCoordinator(navigationController: UINavigationController())
let homeViewController = homeCoordinator.rootViewController
homeViewController.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), selectedImage: UIImage(systemName: "house.fill"))
homeCoordinator.start()
// Search Coordinator
searchCoordinator = SearchCoordinator(navigationController: UINavigationController())
let searchViewController = searchCoordinator.rootViewController
searchViewController.tabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass"), selectedImage: UIImage(systemName: "magnifyingglass"))
searchCoordinator.start()
// Profile Coordinator
profileCoordinator = ProfileCoordinator(navigationController: UINavigationController())
let profileViewController = profileCoordinator.rootViewController
profileViewController.tabBarItem = UITabBarItem(title: "Profile", image: UIImage(systemName: "person"), selectedImage: UIImage(systemName: "person.fill"))
profileCoordinator.start()
super.init()
controllers.append(homeViewController)
controllers.append(searchViewController)
controllers.append(profileViewController)
tabController.viewControllers = controllers
tabController.tabBar.tintColor = UIColor(asset: Asset.Colors.yellow)
tabController.tabBar.isTranslucent = false
}
}
and TabBarCoordinatorProtocol file incloude this codes
public protocol TabBarCoordinatorProtocol {
var rootViewController: UIViewController { get }
}
Related
I have three viewcontrollers that all have buttons switch to a fourth viewcontroller. On this fourth viewcontroller, I have a back button, which I want to take me back to the viewcontroller that I was originally at.
I can't just use the control drag since that only let's you go to a single controller. How can I programmatically have it send the user to the most recent viewcontroller?
import UIKit
class ViewController: UIViewController {
let tabBar = UITabBarController()
var selectedIndex: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tab()
}
#IBAction func goto(_ sender: Any) {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "FrekansViewController") as! FrekansViewController
self.present(nextViewController, animated:true, completion:nil)
}
func tab() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let homeVC = UIViewController()
var streamVC = UIViewController()
var liveVC = UIViewController()
var searchVC = UIViewController()
streamVC = storyboard.instantiateViewController(withIdentifier: "StreamViewController")
liveVC = storyboard.instantiateViewController(withIdentifier: "LiveViewController")
searchVC = storyboard.instantiateViewController(withIdentifier: "SearchViewController")
tabBar.viewControllers = [homeVC,streamVC, liveVC, searchVC]
let itemHome = UITabBarItem(title: "Home", image: UIImage.init(systemName: "house.fill") , tag:0)
let itemStream = UITabBarItem(title: "List", image: UIImage.init(systemName: "waveform.path") , tag:1)
let itemLive = UITabBarItem(title: "Radio", image: UIImage.init(systemName: "play.fill") , tag:2)
let itemSearch = UITabBarItem(title: "Search", image: UIImage.init(systemName: "magnifyingglass"), tag: 3)
homeVC.tabBarItem = itemHome
streamVC.tabBarItem = itemStream
liveVC.tabBarItem = itemLive
searchVC.tabBarItem = itemSearch
self.view.addSubview(tabBar.view)
}
}
Try to embed the controllers inside NavigationController then you can use :
navigationController?.popViewController(animated: true)
This would do the desired functionality for you.
I have 3 view controllers in a UITabBarController. In only one view controller I would like to place it in a navigation controller. What is the proper way of doing this so that only one view controller has a Navigation Controller? I would like aController to be in a navigation controller.
import UIKit
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let mController = MViewController()
mpController.tabBarItem = UITabBarItem(title: "view1", image: UIImage(named: "viewoneimage"), tag: 0)
let inputController = InputViewController()
inputController.tabBarItem = UITabBarItem(title: "Input", image: UIImage(named: "plus"), tag: 1)
let aController = ATableViewController()
aController.tabBarItem = UITabBarItem(title: "custom", image: UIImage(named: "person.fill"), tag: 2)
let navController = UINavigationController()
// aController.navigationController = navController
viewControllers = [mController, inputController, aController, navController]
// Do any additional setup after loading the view.
}
}
You must embend your UIViewController inside the Navigation Controllers and initialize your tab menu with your Navigation Controllers.
Also for each tab you will have different Navigation Controller
Your code should look like that.
import UIKit
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let mController = MViewController()
mpController.tabBarItem = UITabBarItem(title: "view1", image: UIImage(named: "viewoneimage"), tag: 0)
let inputController = InputViewController()
inputController.tabBarItem = UITabBarItem(title: "Input", image: UIImage(named: "plus"), tag: 1)
let aController = ATableViewController()
aController.tabBarItem = UITabBarItem(title: "custom", image: UIImage(named: "person.fill"), tag: 2)
let navMController = UINavigationController(rootViewController: mpController)
let navInputController = UINavigationController(rootViewController: inputController)
let navaController = UINavigationController(rootViewController: aController)
viewControllers = [navMController, navInputController, navaController]
}
}
I need replace the last view controller, depending on the condition. Into TabBarController I have 4 view controllers, last view controller it's LoginVC. If I'm already logged in I need replace LoginVC to ProfileVC.
I try:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if tabBarController.selectedIndex == 3 && !DefaultsManager.instance.getUserToken().isEmpty {
showProfile()
return false
}
return true
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
if tabBarController.selectedIndex == 3 && !DefaultsManager.instance.getUserToken().isEmpty {
showProfile()
}
}
func showProfile() {
let profile = ProfileVC.instantiateNCFromStoryboard()
self.viewControllers?[3] = profile
}
But it's does't work for me.
screen with login screen
screen profile screen with my condition
In AppDelegate check user login status and change the last view controller and its tabBarItem
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let rootVC = self.window?.rootViewController as? UITabBarController, var viewControllers = rootVC.viewControllers {
viewControllers.removeLast()
if userLoggedIn {
let profileVC = ProfileVC()
//profileVC.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "imgName"), selectedImage: UIImage(named: "imgName"))
profileVC.tabBarItem = UITabBarItem(title: "Profile", image: nil, selectedImage: nil)
viewControllers.append(profileVC)
} else {
let loginVC = LoginVC()
//loginVC.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "imgName"), selectedImage: UIImage(named: "imgName"))
loginVC.tabBarItem = UITabBarItem(title: "Login", image: nil, selectedImage: nil)
viewControllers.append(loginVC)
}
rootVC.viewControllers = viewControllers
}
return true
}
In LoginVC upon successfull login, remove LoginVC from tabBarController and add ProfileVC
#objc func loginBtnAction(_ sender: UIButton) {
if var viewControllers = self.tabBarController?.viewControllers {
viewControllers.removeLast()
let profileVC = ProfileVC()
//profileVC.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "imgName"), selectedImage: UIImage(named: "imgName"))
profileVC.tabBarItem = UITabBarItem(title: "Profile", image: nil, selectedImage: nil)
viewControllers.append(profileVC)
self.tabBarController?.viewControllers = viewControllers
}
}
In Logout button action from ProfileVC, remove ProfileVC from tabBarController and add LoginVC
#objc func logoutBtnAction(_ sender: UIButton) {
if var viewControllers = self.tabBarController?.viewControllers {
viewControllers.removeLast()
let loginVC = LoginVC()
//loginVC.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "imgName"), selectedImage: UIImage(named: "imgName"))
loginVC.tabBarItem = UITabBarItem(title: "Login", image: nil, selectedImage: nil)
viewControllers.append(loginVC)
self.tabBarController?.viewControllers = viewControllers
}
}
I am working without Storyboards.
After the successful login, I'd like to add a tabBar into my viewControllers.
I created another viewController called tabBar controller with the code:
class TabBarController: UITabBarController,UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
// Create Tab one
let tabOne = Home()
let tabOneBarItem = UITabBarItem(title: "Collection", image: #imageLiteral(resourceName: "matchTabIcon"), selectedImage: #imageLiteral(resourceName: "matchTabIconSelected"))
tabOne.tabBarItem = tabOneBarItem
// Create Tab two
let tabTwo = ScoutingVC()
let tabTwoBarItem2 = UITabBarItem(title: "Scouting", image: #imageLiteral(resourceName: "scouting"), selectedImage:#imageLiteral(resourceName: "scoutingSelected"))
tabTwo.tabBarItem = tabTwoBarItem2
self.viewControllers = [tabOne, tabTwo]
}
// UITabBarControllerDelegate method
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
print("Selected \(viewController.title!)")
}
}
What is the correct way to add this to all of my VCs?
I tried
self.vc.addSubView(tabBarController)
and also to create a func() in the first VC (index: 0), but either the tabBar is not there, or if there, doesn't switch between viewControllers.
func showTabBarController() {
// Create Tab one
let home = Home()
let homeTabBarItem = UITabBarItem(title: "Collection", image: #imageLiteral(resourceName: "matchTabIcon"), selectedImage: #imageLiteral(resourceName: "matchTabIconSelected"))
home.tabBarItem = homeTabBarItem
let navHome = UINavigationController.init(rootViewController: home)
// Create Tab two
let scouting = ScoutingVC()
let scoutingTabBarItem = UITabBarItem(title: "Scouting", image: #imageLiteral(resourceName: "scouting"), selectedImage: #imageLiteral(resourceName: "scoutingSelected"))
scouting.tabBarItem = scoutingTabBarItem
let navScouting = UINavigationController.init(rootViewController: scouting)
//showTabBar
tabBarCnt.viewControllers = [navHome, navScouting]
self.view.addSubview(tabBarCnt.tabBar)
}
Instead of using self.vc.addSubView(tabBarController) use present(TabBarController(), animated: false, completion: nil)
I am programicaly loading Storyboards into a UITabBarController but for some reason UITabBarItem are not loading the image or selectedImage for all except the first Tab are not loading
But if you tap other tabs icons load
Loading Storyboard Example
import UIKit
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let defaultImag = UIImage(named: "Profile")?.withRenderingMode(.alwaysOriginal)
let selectedImag = UIImage(named: "Profile_selected")?.withRenderingMode(.alwaysOriginal)
self.tabBarItem = UITabBarItem(title: nil, image: defaultImag, selectedImage: selectedImag)
self.tabBarItem.imageInsets = UIEdgeInsets(top: 10, left: 0, bottom: -10, right: 0);
}
}
UITabBarController
import UIKit
class TabBarViewController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let discoverStoryboard = UIStoryboard(name: "Discover", bundle: nil)
let discoverViewController = discoverStoryboard.instantiateInitialViewController()! as UIViewController
let favouritesStoryboard = UIStoryboard(name: "Favourites", bundle: nil)
let favouritesViewController = favouritesStoryboard.instantiateInitialViewController()! as! FavouritesViewController
let profileStoryboard = UIStoryboard(name: "Profile", bundle: nil)
let profileViewController = profileStoryboard.instantiateInitialViewController()! as UIViewController
self.viewControllers = [discoverViewController, favouritesViewController, profileViewController]
}
}
private func createTabForStoryBoard(storyBoardName: String, title: String, imageName :String, tag: Int) -> (UINavigationController) {
let storyboard = UIStoryboard(name: storyBoardName as String, bundle: nil)
let viewController = storyboard.instantiateInitialViewController() as! UIViewController
let image = UIImage(named: imageName)
let tabBarItem:UITabBarItem = UITabBarItem.init(title: NSLocalizedString(title, comment: "Tab Bar Names") , image: image, tag: 0)
viewController.tabBarItem = tabBarItem
return viewController
}
// MARK: Custom Methods
func setTabBarViewControllers() {
let discoverViewController = self.createTabForStoryBoard("Discover", title: "Discover", imageName: "<image-name>", tag: 1)
let favouritesViewController = self.createTabForStoryBoard("Favourites", title: "Favourites", imageName: "<image-name>", tag: 2)
let profileViewController = self.createTabForStoryBoard("Profile", title: "Profile", imageName: "<image-name>", tag: 3)
let tabBarViewControllers = [discoverViewController, favouritesViewController, profileViewController]
self.viewControllers = tabBarViewControllers
}