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]
}
}
Related
I am facing a problem. When I want to change the View for a Tab View Controller, my application gives a black screen.
And here is my code to change view:
let homeViewController = self.storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
self.view.window?.rootViewController = homeViewController
self.view.window?.makeKeyAndVisible()
Constants.swift:
import Foundation
struct Constants {
struct Storyboard {
static let homeViewController = "homeVC"
}
}
homeVC is the first View of TabBarController, with the Label.
This is my way. I am not using storyboard by the way. I am using xib.
let dashboardVc = DashboardTabController()
self.window!.rootViewController = dashboardVc
self.window!.makeKeyAndVisible()
self.window?.overrideUserInterfaceStyle = .light
and then in dashboardTabController type this one.
import UIKit
class DashboardTabController: UITabBarController {
#IBOutlet weak var dashboardTabBar: UITabBar!
override func viewDidLoad() {
super.viewDidLoad()
let firstViewController = HomeViewController()
firstViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "ic_home_24px"), selectedImage: UIImage(named: "ic_home_24px"))
let secondViewController = AddContactViewController()
secondViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "ic_group_add_24px"), selectedImage: UIImage(named: "ic_group_add_24px"))
let tabBarList = [firstViewController, secondViewController]
viewControllers = tabBarList
}
}
don't forget in DashBoardTabController xib, implement the UITabBar in bottom. Hopefully it's helpful. Just mention me if you need more help on executing this.
I have tabbar controller which done programmatically. And tab bar is working fine. In stroyboard, i have created firstViewController and assigned class name firstViewController. When i tried to tab on first vc on tab bar controller to navigates to first viewcontroller and it crash. if i give programmatically mean it works fine.
How to navigate from programmatically tab bar controller to storyboard view controller.
here is my code of tab bar controller:
let tabBarCnt = UITabBarController()
func createTabBarController() {
let firstVC = FViewController()
firstVC.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
let secondVC = SViewController()
secondVC.tabBarItem = UITabBarItem(tabBarSystemItem: .more, tag: 1)
let thirdVC = ViewController()
thirdVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 2)
let fourthVC = ViewController()
fourthVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 3)
if UIDevice.current.userInterfaceIdiom == .pad {
let controllerArray = [firstVC, secondVC, thirdVC, fourthVC]
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
} else {
let controllerArray = [firstVC, secondVC]
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
}
Here is my firstVC of firstViewController code:
import UIKit
class FViewController: UIViewController, UITabBarDelegate {
#IBOutlet weak var firstBtn: UIButton!
#IBOutlet weak var fview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blue
// self.fview.backgroundColor = .brown
// Do any additional setup after loading the view.
}
}
Please try below code. you can give view controller identifier by interface builder.
let tabBarCnt = UITabBarController()
func createTabBarController() {
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let firstVC = storyboard?.instantiateViewControllerWithIdentifier("FViewController")
firstVC.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
let secondVC = storyboard?.instantiateViewControllerWithIdentifier("SViewController")
secondVC.tabBarItem = UITabBarItem(tabBarSystemItem: .more, tag: 1)
let thirdVC = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
thirdVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 2)
let fourthVC = storyboard?.instantiateViewControllerWithIdentifier("ViewController")
fourthVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 3)
var controllerArray = [firstVC, secondVC]
if UIDevice.current.userInterfaceIdiom == .pad {
controllerArray += [thirdVC, fourthVC]
}
tabBarCnt.viewControllers = controllerArray.map{ UINavigationController.init(rootViewController: $0)}
self.view.addSubview(tabBarCnt.view)
}
So programatically navigation controller is created and then assigned FirstVC or XVC as root for that navigation controller. This action has been repeated for all tabs.
So, in storyboard instead of dragging view controller you need to take navigation controller. I have attached screenshots.
Default it will give TableViewVC as root for Navigation controller
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)
My goal is to display a tab view controller that manages multiple tabs that consist of navigation controllers containing view controllers.
I set the tab view controller BaseTabBarController as window my root view controller in AppDelegate. My custom tab view controller looks like this:
class BaseTabBarController: ESTabBarController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
let v1 = BaseNavigationController(rootViewController: SubscriptionsController())
let v2 = BaseNavigationController(rootViewController: SubscriptionsController())
v1.tabBarItem = ESTabBarItem(title: "Home", image: #imageLiteral(resourceName: "tab_bar_home"), selectedImage: #imageLiteral(resourceName: "tab_bar_home"))
v2.tabBarItem = ESTabBarItem(title: "Home", image: #imageLiteral(resourceName: "tab_bar_home"), selectedImage: #imageLiteral(resourceName: "tab_bar_home"))
self.viewControllers = [v1, v2]
self.hidesBottomBarWhenPushed = true
}
}
My custom navigation controller class is an empty subclass of a navigation controller.
The problem is that the app displays a tab bar for a fraction of a second, and immediately turns into a black screen (console message: "Presenting view controllers on detached view controllers is discouraged"). What did I do wrong?
there has got to be something wrong with some other parts of your code. when i take your code and use it like this everything works as expected:
class BaseTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
let v1 = UINavigationController(rootViewController: UIViewController())
let v2 = UINavigationController(rootViewController: UIViewController())
v1.tabBarItem = UITabBarItem(title: "Home", image: nil, selectedImage: nil)
v2.tabBarItem = UITabBarItem(title: "Home", image: nil, selectedImage: nil)
self.viewControllers = [v1, v2]
self.hidesBottomBarWhenPushed = true
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = BaseTabBarController()
window?.makeKeyAndVisible()
return true
}
I want to call the UITabBarController after signing in from a UIViewController
I use the pushViewController but it doesn't work.
Here's my code
let dashboarController = DashboardTabBarController()
self.navigationController?.pushViewController(dashboarController, animated: false)
self.dismiss(animated: true, completion: nil)
This is my code in DashboardController
DashboardTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.view.backgroundColor = UIColor.white
print("test")
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let tabOne = MerchantTableViewController()
let tabOneBarItem = UITabBarItem(title: "Merchant", image: UIImage(named: "icon_merchant"), selectedImage: UIImage(named: "icon_merchant"))
tabOne.tabBarItem = tabOneBarItem
let tabTwo = RewardsViewController()
let tabTwoBarItem2 = UITabBarItem(title: "Rewards", image: UIImage(named: "icon_reward"), selectedImage: UIImage(named: "icon_reward"))
tabTwo.tabBarItem = tabTwoBarItem2
let tabThree = ViewController()
let tabTwoBarItem3 = UITabBarItem(title: "Promos", image: UIImage(named: "icon_promos"), selectedImage: UIImage(named: "icon_promos"))
tabThree.tabBarItem = tabTwoBarItem3
let tabFour = MerchantTableViewController()
let tabTwoBarItem4 = UITabBarItem(title: "Transactions", image: UIImage(named: "icon_card"), selectedImage: UIImage(named: "icon_card"))
tabFour.tabBarItem = tabTwoBarItem4
let tabFive = ProfileViewController()
let tabTwoBarItem5 = UITabBarItem(title: "Profile", image: UIImage(named: "icon_profile"), selectedImage: UIImage(named: "icon_profile"))
tabFive.tabBarItem = tabTwoBarItem5
self.viewControllers = [tabOne, tabTwo, tabThree, tabFour, tabFive]
}
}
I'm a newbie in iOS development. Thanks
Apple doc says : A navigation controller object manages the currently displayed screens using the navigation stack, which is represented by an array of view controllers. The first view controller in the array is the root view controller. The last view controller in the array is the view controller currently being displayed. You add and remove view controllers from the stack using segues or using the methods of this class.
So now , if you don't wanted to you use UINavigationController and add the UIViewController, follow below methods:
Present ViewController
Add as a Child VC
You should have the view controller from which you are navigating is in the navigation. If it is not, then create a navigation view controller's object with root having you source view controller as root view controller.
If you don't want to use navigation controller then you can use PresentViewController method to present view controller.