moreNavigationController is always nil in UITabBarController - ios

I'm trying to customize the title of my More button in my UITabBarController as I'm doing the app in another language. I subclassed UITabBarController to be able to access the tabBarController property. Unfortunately, it's always nil whether I put it in viewDidLoad or viewDidAppear(_). Any thoughts on how I can edit it?
import UIKit
class ControllerVC: UITabBarController {
let uiManager = UIManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
if let tabBarItem = tabBarController?.moreNavigationController.tabBarItem {
let deselectedImage = tabBarItem.image
let selectedImage = tabBarItem.selectedImage
tabBarController!.moreNavigationController.tabBarItem = UITabBarItem(title: "بیشتر", image: deselectedImage, selectedImage: selectedImage)
} else {
uiManager.showActivityIndicator(self)
}
}
}

The problem is not with moreNavigationController. The problem is with tabBarController. Your class is a UITabBarController. A tab bar controller's tabBarController property is always nil.
Just do:
let tabBarItem = moreNavigationController.tabBarItem
let deselectedImage = tabBarItem.image
let selectedImage = tabBarItem.selectedImage
moreNavigationController.tabBarItem = UITabBarItem(title: "بیشتر", image: deselectedImage, selectedImage: selectedImage)

Related

Is there a way to change Tabbar images and action from embedded ViewController?

I have 5 ViewController that embedded with TabbarController. I created a class Tabbar to customize my Tabbar like :
class Tabbar: UITabBarController,UITabBarControllerDelegate {
var tabBarIteam = UITabBarItem()
#IBOutlet weak var tabbar: UITabBar!
override func viewDidLoad() {
super.viewDidLoad()
// THIS IS FOR FİRST TABBAR ITEM
let selectedImage1 = UIImage(named: "vitrin_active")?.withRenderingMode(.alwaysOriginal)
let deSelectedImage1 = UIImage(named: "vitrin_deactive")
tabBarIteam = self.tabBar.items![0]
tabBarIteam.image = deSelectedImage1
tabBarIteam.selectedImage = selectedImage1
.... I HAVE ALSO 4 MORE.
}
In my firstViewController , There is a button action
#IBAction func ChangeTabbarimageAndAction(_ sender: Any) {
..
}
I want to change Tabbar images and actions (like push) when FirstView's ChangeTabbarimageAndAction tapped. Is this possible? If yes, How could I do? I searched in SO but can't find any solutions.
If you want to change the current UIViewController's tab bar image or title you can access the tabBarItem from the UIViewController and can change it's properties like this:
#IBAction func ChangeTabbarimageAndAction(_ sender: Any) {
tabBarItem.image = UIImage(named: "New Image name")
tabBarItem.selectedImage = UIImage(named: "NewSelectedImageName")
tabBarItem.title = "New Title"
}
You can change action in delegate method of tabbar
class yourclass: UIViewController, UITabBarDelegate {
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print("push or present action")
}
}
And for setting the image you can use
let firstViewController:UIViewController = UIViewController()
// The following statement is what you need
let customTabBarItem:UITabBarItem = UITabBarItem(title: nil, image: UIImage(named: "YOUR_IMAGE_NAME"), selectedImage: UIImage(named: "YOUR_IMAGE_NAME"))
firstViewController.tabBarItem = customTabBarItem

How can I get rid of the 2nd navigation bar? They are directly on top of one another

click the link to view the image
There is something above the navigationbar, and I'm confused on what it is and how to get rid of it.
here is my tabController code
{import UIKit
class TabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
delegate = self
authenticateUserAndConfigureView()
}
func setupViewControllers() {
let home = templateNavController(viewController: DiscoverViewController(), image: UIImage(named: "house")!, title: "Home")
let search = templateNavController(viewController: SearchViewController(), image: UIImage(named: "search")!, title: "Discover")
let problem = templateNavController(viewController: NewProblemViewController(), image: UIImage(named:"addproblem")!, title: "Add New Problem")
let chat = templateNavController(viewController: MessageViewController(), image: UIImage(named: "chat")!, title: "Chat")
let profile = templateNavController(viewController: ProfileViewController(), image: UIImage(named: "profile")!, title: "Profile")
self.viewControllers = [home, search, problem, chat, profile]
}
func authenticateUserAndConfigureView() {
DispatchQueue.main.async {
if Auth.auth().currentUser == nil {
let navController = UINavigationController(rootViewController: LoggedOut())
navController.modalPresentationStyle = .fullScreen
self.present(navController, animated: true, completion: nil)
} else {
self.setupViewControllers()
}
}
}
func templateNavController(viewController: UIViewController, image: UIImage, title: String) -> UINavigationController {
let navController = UINavigationController(rootViewController: viewController)
navController.tabBarItem.image = image
navController.navigationBar.backgroundColor = .white
navController.tabBarItem.title = title
return navController
}
}
}
You can always use 'Debug View Hierarchy' xCode tool to see views hierarchy in a screen.
Just run the app on a simulator or device and click 'Debug View Hierarchy' when your screen is active.
Here you can rotate screen and see all active layers. Once you select a layer you can check it name and position in hierarchy on the left bar.
Hey Guys I figured it out! My mistake was that I cast my original TabBarController as a UINavigationController before setting the view controllers on there. Thus there was a navigation bar from the mistake UINavController and another navigation bar from the navigation controller that I cast on each view controller.

Black Screen Tab Bar Controller

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.

Embed custom tab bar controller after loginVC programmatically

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)

swift 3 keep bottom tabbar on children windows?

i am trying to keep bottom tab bar in children viewcontroller , my issue when i open children window its open without bottom tabs , how i can keep bottom tabs stuck everywhere in the app ?
this is the class of main tabs window ( landing )
class vc_landingPage: UITabBarController , UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
//Delegate methods
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
print("Should select viewController: \(String(describing: viewController.title)) ?")
return true;
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let sb2 = UIStoryboard(name: "pools", bundle: nil)
let v1 = sb2.b_pools.instantiateInitialViewController()!
v1.tabBarItem = UITabBarItem( title : "" , image: UIImage(named: "icon-pools-x30"), selectedImage: UIImage(named: "icon-pools-x30-active"))
let sb = UIStoryboard(name: "myProfile", bundle: nil)
let v2 = sb.instantiateInitialViewController()!
v2.tabBarItem = UITabBarItem( title : "" , image: UIImage(named: "icon-profile-x30"), selectedImage: UIImage(named: "icon-profile-x30-active"))
self.viewControllers = [v1,v2]
self.selectedIndex = 1
}
}
Please you must manage the children window in a UINavigationController.
let v1 = sb2.b_pools.instantiateInitialViewController()!
let navi1 = UINavigationController.init(rootViewController: v1)
let v2 = sb.instantiateInitialViewController()!
let navi2 = UINavigationController.init(rootViewController: v2)
self.viewControllers = [navi1,navi2]
Make sure your BOTTOM BAR is not none, make sure it is not set to any of your view controller or your tab bar controller

Resources