I've created a custom tab bar that is displaying tab bar items correctly. When I select a tab / icon the tab bar item's view controller is displayed but the icon does not change to the 'Selected image' icon i.e. the icons don't change when their view controller is being shown.
What am I doing wrong? How can I get the icons to update to the images that I've set on IB as the selected images?
Here is some of my code:
class CustomTabBarController: UITabBarController, CustomTabBarDataSource, CustomTabBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.isHidden = true
let customTabBar = CustomTabBar(frame: self.tabBar.frame)
customTabBar.datasource = self
customTabBar.delegate = self
customTabBar.setup()
self.view.addSubview(customTabBar)
}
// MARK: - CustomTabBarDataSource
func tabBarItemsInCustomTabBar(_ tabBarView: CustomTabBar) -> [UITabBarItem] {
return tabBar.items!
}
// MARK: - CustomTabBarDelegate
func didSelectViewController(_ tabBarView: CustomTabBar, atIndex index: Int) {
self.selectedIndex = index
}
}
class CustomTabBar: UIView {
var tabBarItems: [UITabBarItem]!
var customTabBarItems: [CustomTabBarItem]!
var tabBarButtons: [UIButton]!
func setup() {
tabBarItems = datasource.tabBarItemsInCustomTabBar(self)
customTabBarItems = []
tabBarButtons = []
let containers = createTabBarItemContainers()
createTabBarItems(containers)
}
func createTabBarItems(_ containers: [CGRect]) {
var index = 0
for item in tabBarItems {
let container = containers[index]
let customTabBarItem = CustomTabBarItem(frame: container)
customTabBarItem.setup(item)
self.addSubview(customTabBarItem)
customTabBarItems.append(customTabBarItem)
let button = UIButton(frame: CGRect(x: 0, y: 0, width: container.width, height: container.height))
button.addTarget(self, action: #selector(CustomTabBar.barItemTapped(_:)), for: UIControlEvents.touchUpInside)
customTabBarItem.addSubview(button)
tabBarButtons.append(button)
index += 1
}
}
func barItemTapped(_ sender : UIButton) {
let index = tabBarButtons.index(of: sender)!
delegate.didSelectViewController(self, atIndex: index)
}
iOS UITabBarController Changing Tab Bar Item Title and Icon For a custom icon, add the required images to the assets folder and set the 'System Item' from earlier to 'custom'. Now, set the icon to be shown when the tab is selected from the 'selected image' drop down and the default tab icon from the 'image' drop down.
To add a tab, first drag a new View Controller object to the storybard. Next control-drag from the tab bar controller to new view controller and select view controllers under Relationship Segue . Your tab bar controller will update with a new tab.
Implement a view controller that can hold some other view controllers. Show one of those view controllers. Show a tab bar at the bottom of the screen over the shown view controller. Switch between the various view controllers when the user taps on a tab bar button.
Change
class CustomTabBar: UIView {
to:
class CustomTabBar: UITabBar {
Then your custom tab bar will act like a tab bar!
Well I had a same kind of functionality and implemented with UITabBarController like this.
enum TabType:Int{
case viewController1 = 0
case viewController2 = 1
case viewController3 = 2
}
class CustomTabbarVC: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
convenience init(userType : UserType){
self.init()
addViewControllers()
setupOnInit()
let tabBar = self.tabBar
tabBar.selectionIndicatorImage = UIImage().createSelectionIndicator(UIColor(red: 22/255, green: 52/255, blue: 89/255, alpha: 1.0), size: CGSize(width: tabBar.frame.width/CGFloat(tabBar.items!.count), height: tabBar.frame.height), lineWidth: 3.0)
}
func setupOnInit(){
delegate = self
tabBar.barStyle = UIBarStyle.black
tabBar.isTranslucent = false
}
func addViewControllers(){
// We will add 3 controllers
let viewController1 = viewController1(nibName: “viewController1”, bundle: nil)
let viewController2 = viewController2(nibName: “viewController2”, bundle: nil)
let viewController3 = viewController3(nibName: “viewController3”, bundle: nil)
let viewController1Navigation = UINavigationController(rootViewController: viewController1)
viewController1Navigation.tabBarItem = getTabbarItem(.viewController1)
viewController1Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
let viewController2Navigation = UINavigationController(rootViewController: viewController2)
viewController2Navigation.tabBarItem = getTabbarItem(.viewController2)
viewController2Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
let viewController3Navigation = UINavigationController(rootViewController: viewController3)
viewController3Navigation.tabBarItem = getTabbarItem(.viewController3)
viewController3Navigation.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0)
viewControllers = [viewController1Navigation,viewController2Navigation,viewController3Navigation]
}
func getTabbarItem(_ tabType:TabType)->UITabBarItem{
// Fetch tab bar item and set image according to it.
var image = String()
var selectedImage = String()
if tabType == .viewController1{
image = “img_viewController1_tab_nonSelected”
selectedImage = “img_viewController1_tab_Selected”
}else if tabType == .viewController2{
image = “img_viewController2_tab_nonSelected”
selectedImage = “img_viewController2_tab_Selected”
}else if tabType == .viewController3{
image = “img_viewController3_tab_nonSelected”
selectedImage = “img_viewController3_tab_Selected”
}else{
print("Unknown tab type")
}
if let imageName:String = image,let selectedImageName:String = selectedImage{
return UITabBarItem(title: nil, image: UIImage(named: imageName)?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: selectedImageName)?.withRenderingMode(.alwaysOriginal))
}else{
return UITabBarItem()
}
}
}
extension UIImage {
func createSelectionIndicator(_ color: UIColor, size: CGSize, lineWidth: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(CGRect(x: 0, y: size.height - lineWidth, width: size.width, height: lineWidth))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
How to implement in App delegate
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
var customTabbarVC: CustomTabbarVC?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
customTabbarVC = customTabbarVC() // It will invoke init methods of customtabbarvc
window?.rootViewController = customTabbarVC // Here your tab bar controller will setup
return true
}
// Other APP DELEGATE METHODS
}
Let me know if you have any questions..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With